Process Alt-Svc headers.
[chromium-blink-merge.git] / content / browser / renderer_host / render_process_host_impl.cc
blob79f1c3c671e736f647418138e6b33b59f036d932
1 // Copyright 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 #include "base/base_switches.h"
15 #include "base/bind.h"
16 #include "base/bind_helpers.h"
17 #include "base/callback.h"
18 #include "base/command_line.h"
19 #include "base/debug/dump_without_crashing.h"
20 #include "base/files/file.h"
21 #include "base/lazy_instance.h"
22 #include "base/location.h"
23 #include "base/logging.h"
24 #include "base/metrics/field_trial.h"
25 #include "base/metrics/histogram.h"
26 #include "base/process/process_handle.h"
27 #include "base/profiler/scoped_tracker.h"
28 #include "base/rand_util.h"
29 #include "base/single_thread_task_runner.h"
30 #include "base/stl_util.h"
31 #include "base/strings/string_number_conversions.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/trace_event/trace_event.h"
38 #include "base/tracked_objects.h"
39 #include "cc/base/switches.h"
40 #include "components/scheduler/common/scheduler_switches.h"
41 #include "content/browser/appcache/appcache_dispatcher_host.h"
42 #include "content/browser/appcache/chrome_appcache_service.h"
43 #include "content/browser/background_sync/background_sync_service_impl.h"
44 #include "content/browser/bad_message.h"
45 #include "content/browser/bluetooth/bluetooth_dispatcher_host.h"
46 #include "content/browser/browser_child_process_host_impl.h"
47 #include "content/browser/browser_main.h"
48 #include "content/browser/browser_main_loop.h"
49 #include "content/browser/browser_plugin/browser_plugin_message_filter.h"
50 #include "content/browser/cache_storage/cache_storage_context_impl.h"
51 #include "content/browser/cache_storage/cache_storage_dispatcher_host.h"
52 #include "content/browser/child_process_security_policy_impl.h"
53 #include "content/browser/device_sensors/device_light_message_filter.h"
54 #include "content/browser/device_sensors/device_motion_message_filter.h"
55 #include "content/browser/device_sensors/device_orientation_message_filter.h"
56 #include "content/browser/dom_storage/dom_storage_context_wrapper.h"
57 #include "content/browser/dom_storage/dom_storage_message_filter.h"
58 #include "content/browser/download/mhtml_generation_manager.h"
59 #include "content/browser/fileapi/chrome_blob_storage_context.h"
60 #include "content/browser/fileapi/fileapi_message_filter.h"
61 #include "content/browser/frame_host/render_frame_message_filter.h"
62 #include "content/browser/geofencing/geofencing_dispatcher_host.h"
63 #include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
64 #include "content/browser/gpu/compositor_util.h"
65 #include "content/browser/gpu/gpu_data_manager_impl.h"
66 #include "content/browser/gpu/gpu_process_host.h"
67 #include "content/browser/gpu/shader_disk_cache.h"
68 #include "content/browser/histogram_message_filter.h"
69 #include "content/browser/indexed_db/indexed_db_context_impl.h"
70 #include "content/browser/indexed_db/indexed_db_dispatcher_host.h"
71 #include "content/browser/loader/resource_message_filter.h"
72 #include "content/browser/loader/resource_scheduler_filter.h"
73 #include "content/browser/media/capture/audio_mirroring_manager.h"
74 #include "content/browser/media/media_internals.h"
75 #include "content/browser/media/midi_host.h"
76 #include "content/browser/message_port_message_filter.h"
77 #include "content/browser/mime_registry_message_filter.h"
78 #include "content/browser/mojo/mojo_application_host.h"
79 #include "content/browser/navigator_connect/service_port_service_impl.h"
80 #include "content/browser/notifications/notification_message_filter.h"
81 #include "content/browser/permissions/permission_service_context.h"
82 #include "content/browser/permissions/permission_service_impl.h"
83 #include "content/browser/profiler_message_filter.h"
84 #include "content/browser/push_messaging/push_messaging_message_filter.h"
85 #include "content/browser/quota_dispatcher_host.h"
86 #include "content/browser/renderer_host/clipboard_message_filter.h"
87 #include "content/browser/renderer_host/database_message_filter.h"
88 #include "content/browser/renderer_host/file_utilities_message_filter.h"
89 #include "content/browser/renderer_host/gamepad_browser_message_filter.h"
90 #include "content/browser/renderer_host/gpu_message_filter.h"
91 #include "content/browser/renderer_host/media/audio_input_renderer_host.h"
92 #include "content/browser/renderer_host/media/audio_renderer_host.h"
93 #include "content/browser/renderer_host/media/media_stream_dispatcher_host.h"
94 #include "content/browser/renderer_host/media/peer_connection_tracker_host.h"
95 #include "content/browser/renderer_host/media/video_capture_host.h"
96 #include "content/browser/renderer_host/memory_benchmark_message_filter.h"
97 #include "content/browser/renderer_host/pepper/pepper_message_filter.h"
98 #include "content/browser/renderer_host/pepper/pepper_renderer_connection.h"
99 #include "content/browser/renderer_host/render_message_filter.h"
100 #include "content/browser/renderer_host/render_view_host_delegate.h"
101 #include "content/browser/renderer_host/render_view_host_impl.h"
102 #include "content/browser/renderer_host/render_widget_helper.h"
103 #include "content/browser/renderer_host/render_widget_host_impl.h"
104 #include "content/browser/renderer_host/text_input_client_message_filter.h"
105 #include "content/browser/renderer_host/websocket_dispatcher_host.h"
106 #include "content/browser/resolve_proxy_msg_helper.h"
107 #include "content/browser/service_worker/service_worker_context_wrapper.h"
108 #include "content/browser/service_worker/service_worker_dispatcher_host.h"
109 #include "content/browser/shared_worker/shared_worker_message_filter.h"
110 #include "content/browser/shared_worker/worker_storage_partition.h"
111 #include "content/browser/speech/speech_recognition_dispatcher_host.h"
112 #include "content/browser/storage_partition_impl.h"
113 #include "content/browser/streams/stream_context.h"
114 #include "content/browser/tracing/trace_message_filter.h"
115 #include "content/browser/webui/web_ui_controller_factory_registry.h"
116 #include "content/common/child_process_host_impl.h"
117 #include "content/common/child_process_messages.h"
118 #include "content/common/content_switches_internal.h"
119 #include "content/common/frame_messages.h"
120 #include "content/common/gpu/gpu_messages.h"
121 #include "content/common/in_process_child_thread_params.h"
122 #include "content/common/mojo/channel_init.h"
123 #include "content/common/mojo/mojo_messages.h"
124 #include "content/common/resource_messages.h"
125 #include "content/common/site_isolation_policy.h"
126 #include "content/common/view_messages.h"
127 #include "content/public/browser/browser_context.h"
128 #include "content/public/browser/content_browser_client.h"
129 #include "content/public/browser/navigator_connect_context.h"
130 #include "content/public/browser/notification_service.h"
131 #include "content/public/browser/notification_types.h"
132 #include "content/public/browser/render_process_host_factory.h"
133 #include "content/public/browser/render_process_host_observer.h"
134 #include "content/public/browser/render_widget_host.h"
135 #include "content/public/browser/render_widget_host_iterator.h"
136 #include "content/public/browser/render_widget_host_view_frame_subscriber.h"
137 #include "content/public/browser/resource_context.h"
138 #include "content/public/browser/user_metrics.h"
139 #include "content/public/browser/worker_service.h"
140 #include "content/public/common/child_process_host.h"
141 #include "content/public/common/content_constants.h"
142 #include "content/public/common/content_switches.h"
143 #include "content/public/common/mojo_channel_switches.h"
144 #include "content/public/common/process_type.h"
145 #include "content/public/common/resource_type.h"
146 #include "content/public/common/result_codes.h"
147 #include "content/public/common/sandboxed_process_launcher_delegate.h"
148 #include "content/public/common/url_constants.h"
149 #include "device/battery/battery_monitor_impl.h"
150 #include "device/vibration/vibration_manager_impl.h"
151 #include "gpu/GLES2/gl2extchromium.h"
152 #include "gpu/command_buffer/client/gpu_switches.h"
153 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
154 #include "gpu/command_buffer/service/gpu_switches.h"
155 #include "ipc/ipc_channel.h"
156 #include "ipc/ipc_logging.h"
157 #include "ipc/ipc_switches.h"
158 #include "ipc/mojo/ipc_channel_mojo.h"
159 #include "media/base/media_switches.h"
160 #include "net/url_request/url_request_context_getter.h"
161 #include "ppapi/shared_impl/ppapi_switches.h"
162 #include "storage/browser/fileapi/sandbox_file_system_backend.h"
163 #include "third_party/icu/source/common/unicode/unistr.h"
164 #include "third_party/icu/source/i18n/unicode/timezone.h"
165 #include "third_party/skia/include/core/SkBitmap.h"
166 #include "ui/base/ui_base_switches.h"
167 #include "ui/events/event_switches.h"
168 #include "ui/gfx/switches.h"
169 #include "ui/gl/gl_switches.h"
170 #include "ui/gl/gpu_switching_manager.h"
171 #include "ui/native_theme/native_theme_switches.h"
173 #if defined(OS_ANDROID)
174 #include "content/browser/android/child_process_launcher_android.h"
175 #include "content/browser/media/android/browser_demuxer_android.h"
176 #include "content/browser/mojo/service_registrar_android.h"
177 #include "content/browser/screen_orientation/screen_orientation_message_filter_android.h"
178 #endif
180 #if defined(OS_WIN)
181 #include "base/win/scoped_com_initializer.h"
182 #include "base/win/windows_version.h"
183 #include "content/common/font_cache_dispatcher_win.h"
184 #include "content/common/sandbox_win.h"
185 #include "sandbox/win/src/sandbox_policy.h"
186 #include "ui/gfx/win/dpi.h"
187 #endif
189 #if defined(OS_MACOSX) && !defined(OS_IOS)
190 #include "content/browser/browser_io_surface_manager_mac.h"
191 #endif
193 #if defined(ENABLE_BROWSER_CDMS)
194 #include "content/browser/media/cdm/browser_cdm_manager.h"
195 #endif
197 #if defined(ENABLE_PLUGINS)
198 #include "content/browser/plugin_service_impl.h"
199 #endif
201 #if defined(ENABLE_WEBRTC)
202 #include "content/browser/media/webrtc_internals.h"
203 #include "content/browser/renderer_host/media/media_stream_track_metrics_host.h"
204 #include "content/browser/renderer_host/media/webrtc_identity_service_host.h"
205 #include "content/browser/renderer_host/p2p/socket_dispatcher_host.h"
206 #include "content/common/media/aec_dump_messages.h"
207 #include "content/common/media/media_stream_messages.h"
208 #endif
210 extern bool g_exited_main_message_loop;
212 namespace content {
213 namespace {
215 const char kSiteProcessMapKeyName[] = "content_site_process_map";
217 void CacheShaderInfo(int32 id, base::FilePath path) {
218 ShaderCacheFactory::GetInstance()->SetCacheInfo(id, path);
221 void RemoveShaderInfo(int32 id) {
222 ShaderCacheFactory::GetInstance()->RemoveCacheInfo(id);
225 net::URLRequestContext* GetRequestContext(
226 scoped_refptr<net::URLRequestContextGetter> request_context,
227 scoped_refptr<net::URLRequestContextGetter> media_request_context,
228 ResourceType resource_type) {
229 // If the request has resource type of RESOURCE_TYPE_MEDIA, we use a request
230 // context specific to media for handling it because these resources have
231 // specific needs for caching.
232 if (resource_type == RESOURCE_TYPE_MEDIA)
233 return media_request_context->GetURLRequestContext();
234 return request_context->GetURLRequestContext();
237 void GetContexts(
238 ResourceContext* resource_context,
239 scoped_refptr<net::URLRequestContextGetter> request_context,
240 scoped_refptr<net::URLRequestContextGetter> media_request_context,
241 const ResourceHostMsg_Request& request,
242 ResourceContext** resource_context_out,
243 net::URLRequestContext** request_context_out) {
244 *resource_context_out = resource_context;
245 *request_context_out =
246 GetRequestContext(request_context, media_request_context,
247 request.resource_type);
250 #if defined(ENABLE_WEBRTC)
252 // Allow us to only run the trial in the first renderer.
253 bool has_done_stun_trials = false;
255 // Creates a file used for diagnostic echo canceller recordings for handing
256 // over to the renderer.
257 IPC::PlatformFileForTransit CreateAecDumpFileForProcess(
258 base::FilePath file_path,
259 base::ProcessHandle process) {
260 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
261 base::File dump_file(file_path,
262 base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_APPEND);
263 if (!dump_file.IsValid()) {
264 VLOG(1) << "Could not open AEC dump file, error=" <<
265 dump_file.error_details();
266 return IPC::InvalidPlatformFileForTransit();
268 return IPC::TakeFileHandleForProcess(dump_file.Pass(), process);
271 // Does nothing. Just to avoid races between enable and disable.
272 void DisableAecDumpOnFileThread() {
273 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
275 #endif
277 // the global list of all renderer processes
278 base::LazyInstance<IDMap<RenderProcessHost> >::Leaky
279 g_all_hosts = LAZY_INSTANCE_INITIALIZER;
281 // Map of site to process, to ensure we only have one RenderProcessHost per
282 // site in process-per-site mode. Each map is specific to a BrowserContext.
283 class SiteProcessMap : public base::SupportsUserData::Data {
284 public:
285 typedef base::hash_map<std::string, RenderProcessHost*> SiteToProcessMap;
286 SiteProcessMap() {}
288 void RegisterProcess(const std::string& site, RenderProcessHost* process) {
289 map_[site] = process;
292 RenderProcessHost* FindProcess(const std::string& site) {
293 SiteToProcessMap::iterator i = map_.find(site);
294 if (i != map_.end())
295 return i->second;
296 return NULL;
299 void RemoveProcess(RenderProcessHost* host) {
300 // Find all instances of this process in the map, then separately remove
301 // them.
302 std::set<std::string> sites;
303 for (SiteToProcessMap::const_iterator i = map_.begin();
304 i != map_.end();
305 i++) {
306 if (i->second == host)
307 sites.insert(i->first);
309 for (std::set<std::string>::iterator i = sites.begin();
310 i != sites.end();
311 i++) {
312 SiteToProcessMap::iterator iter = map_.find(*i);
313 if (iter != map_.end()) {
314 DCHECK_EQ(iter->second, host);
315 map_.erase(iter);
320 private:
321 SiteToProcessMap map_;
324 // Find the SiteProcessMap specific to the given context.
325 SiteProcessMap* GetSiteProcessMapForBrowserContext(BrowserContext* context) {
326 DCHECK(context);
327 SiteProcessMap* map = static_cast<SiteProcessMap*>(
328 context->GetUserData(kSiteProcessMapKeyName));
329 if (!map) {
330 map = new SiteProcessMap();
331 context->SetUserData(kSiteProcessMapKeyName, map);
333 return map;
336 // NOTE: changes to this class need to be reviewed by the security team.
337 class RendererSandboxedProcessLauncherDelegate
338 : public SandboxedProcessLauncherDelegate {
339 public:
340 explicit RendererSandboxedProcessLauncherDelegate(IPC::ChannelProxy* channel)
341 #if defined(OS_POSIX)
342 : ipc_fd_(channel->TakeClientFileDescriptor())
343 #endif // OS_POSIX
346 ~RendererSandboxedProcessLauncherDelegate() override {}
348 #if defined(OS_WIN)
349 void PreSpawnTarget(sandbox::TargetPolicy* policy, bool* success) override {
350 AddBaseHandleClosePolicy(policy);
352 const base::string16& sid =
353 GetContentClient()->browser()->GetAppContainerSidForSandboxType(
354 GetSandboxType());
355 if (!sid.empty())
356 AddAppContainerPolicy(policy, sid.c_str());
358 GetContentClient()->browser()->PreSpawnRenderer(policy, success);
361 #elif defined(OS_POSIX)
362 bool ShouldUseZygote() override {
363 const base::CommandLine& browser_command_line =
364 *base::CommandLine::ForCurrentProcess();
365 base::CommandLine::StringType renderer_prefix =
366 browser_command_line.GetSwitchValueNative(switches::kRendererCmdPrefix);
367 return renderer_prefix.empty();
369 base::ScopedFD TakeIpcFd() override { return ipc_fd_.Pass(); }
370 #endif // OS_WIN
372 SandboxType GetSandboxType() override {
373 return SANDBOX_TYPE_RENDERER;
376 private:
377 #if defined(OS_POSIX)
378 base::ScopedFD ipc_fd_;
379 #endif // OS_POSIX
382 const char kSessionStorageHolderKey[] = "kSessionStorageHolderKey";
384 class SessionStorageHolder : public base::SupportsUserData::Data {
385 public:
386 SessionStorageHolder() {}
387 ~SessionStorageHolder() override {}
389 void Hold(const SessionStorageNamespaceMap& sessions, int view_route_id) {
390 session_storage_namespaces_awaiting_close_[view_route_id] = sessions;
393 void Release(int old_route_id) {
394 session_storage_namespaces_awaiting_close_.erase(old_route_id);
397 private:
398 std::map<int, SessionStorageNamespaceMap >
399 session_storage_namespaces_awaiting_close_;
400 DISALLOW_COPY_AND_ASSIGN(SessionStorageHolder);
403 } // namespace
405 RendererMainThreadFactoryFunction g_renderer_main_thread_factory = NULL;
407 base::MessageLoop* g_in_process_thread;
409 base::MessageLoop*
410 RenderProcessHostImpl::GetInProcessRendererThreadForTesting() {
411 return g_in_process_thread;
414 // Stores the maximum number of renderer processes the content module can
415 // create.
416 static size_t g_max_renderer_count_override = 0;
418 // static
419 size_t RenderProcessHost::GetMaxRendererProcessCount() {
420 if (g_max_renderer_count_override)
421 return g_max_renderer_count_override;
423 #if defined(OS_ANDROID)
424 // On Android we don't maintain a limit of renderer process hosts - we are
425 // happy with keeping a lot of these, as long as the number of live renderer
426 // processes remains reasonable, and on Android the OS takes care of that.
427 return std::numeric_limits<size_t>::max();
428 #endif
430 // On other platforms, we calculate the maximum number of renderer process
431 // hosts according to the amount of installed memory as reported by the OS.
432 // The calculation assumes that you want the renderers to use half of the
433 // installed RAM and assuming that each WebContents uses ~40MB. If you modify
434 // this assumption, you need to adjust the ThirtyFourTabs test to match the
435 // expected number of processes.
437 // With the given amounts of installed memory below on a 32-bit CPU, the
438 // maximum renderer count will roughly be as follows:
440 // 128 MB -> 3
441 // 512 MB -> 6
442 // 1024 MB -> 12
443 // 4096 MB -> 51
444 // 16384 MB -> 82 (kMaxRendererProcessCount)
446 static size_t max_count = 0;
447 if (!max_count) {
448 const size_t kEstimatedWebContentsMemoryUsage =
449 #if defined(ARCH_CPU_64_BITS)
450 60; // In MB
451 #else
452 40; // In MB
453 #endif
454 max_count = base::SysInfo::AmountOfPhysicalMemoryMB() / 2;
455 max_count /= kEstimatedWebContentsMemoryUsage;
457 const size_t kMinRendererProcessCount = 3;
458 max_count = std::max(max_count, kMinRendererProcessCount);
459 max_count = std::min(max_count, kMaxRendererProcessCount);
461 return max_count;
464 // static
465 bool g_run_renderer_in_process_ = false;
467 // static
468 void RenderProcessHost::SetMaxRendererProcessCount(size_t count) {
469 g_max_renderer_count_override = count;
472 RenderProcessHostImpl::RenderProcessHostImpl(
473 BrowserContext* browser_context,
474 StoragePartitionImpl* storage_partition_impl,
475 bool is_for_guests_only)
476 : fast_shutdown_started_(false),
477 deleting_soon_(false),
478 #ifndef NDEBUG
479 is_self_deleted_(false),
480 #endif
481 pending_views_(0),
482 mojo_application_host_(new MojoApplicationHost),
483 visible_widgets_(0),
484 backgrounded_(true),
485 is_initialized_(false),
486 id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()),
487 browser_context_(browser_context),
488 storage_partition_impl_(storage_partition_impl),
489 sudden_termination_allowed_(true),
490 ignore_input_events_(false),
491 is_for_guests_only_(is_for_guests_only),
492 gpu_observer_registered_(false),
493 delayed_cleanup_needed_(false),
494 within_process_died_observer_(false),
495 power_monitor_broadcaster_(this),
496 worker_ref_count_(0),
497 max_worker_count_(0),
498 permission_service_context_(new PermissionServiceContext(this)),
499 pending_valuebuffer_state_(new gpu::ValueStateMap()),
500 subscribe_uniform_enabled_(false),
501 weak_factory_(this) {
502 widget_helper_ = new RenderWidgetHelper();
504 ChildProcessSecurityPolicyImpl::GetInstance()->Add(GetID());
506 CHECK(!g_exited_main_message_loop);
507 RegisterHost(GetID(), this);
508 g_all_hosts.Get().set_check_on_null_data(true);
509 // Initialize |child_process_activity_time_| to a reasonable value.
510 mark_child_process_activity_time();
512 if (!GetBrowserContext()->IsOffTheRecord() &&
513 !base::CommandLine::ForCurrentProcess()->HasSwitch(
514 switches::kDisableGpuShaderDiskCache)) {
515 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
516 base::Bind(&CacheShaderInfo, GetID(),
517 storage_partition_impl_->GetPath()));
519 subscribe_uniform_enabled_ =
520 base::CommandLine::ForCurrentProcess()->HasSwitch(
521 switches::kEnableSubscribeUniformExtension);
523 // Note: When we create the RenderProcessHostImpl, it's technically
524 // backgrounded, because it has no visible listeners. But the process
525 // doesn't actually exist yet, so we'll Background it later, after
526 // creation.
529 // static
530 void RenderProcessHostImpl::ShutDownInProcessRenderer() {
531 DCHECK(g_run_renderer_in_process_);
533 switch (g_all_hosts.Pointer()->size()) {
534 case 0:
535 return;
536 case 1: {
537 RenderProcessHostImpl* host = static_cast<RenderProcessHostImpl*>(
538 AllHostsIterator().GetCurrentValue());
539 FOR_EACH_OBSERVER(RenderProcessHostObserver,
540 host->observers_,
541 RenderProcessHostDestroyed(host));
542 #ifndef NDEBUG
543 host->is_self_deleted_ = true;
544 #endif
545 delete host;
546 return;
548 default:
549 NOTREACHED() << "There should be only one RenderProcessHost when running "
550 << "in-process.";
554 void RenderProcessHostImpl::RegisterRendererMainThreadFactory(
555 RendererMainThreadFactoryFunction create) {
556 g_renderer_main_thread_factory = create;
559 RenderProcessHostImpl::~RenderProcessHostImpl() {
560 #ifndef NDEBUG
561 DCHECK(is_self_deleted_)
562 << "RenderProcessHostImpl is destroyed by something other than itself";
563 #endif
565 // Make sure to clean up the in-process renderer before the channel, otherwise
566 // it may still run and have its IPCs fail, causing asserts.
567 in_process_renderer_.reset();
569 ChildProcessSecurityPolicyImpl::GetInstance()->Remove(GetID());
571 if (gpu_observer_registered_) {
572 ui::GpuSwitchingManager::GetInstance()->RemoveObserver(this);
573 gpu_observer_registered_ = false;
576 // We may have some unsent messages at this point, but that's OK.
577 channel_.reset();
578 while (!queued_messages_.empty()) {
579 delete queued_messages_.front();
580 queued_messages_.pop();
583 UnregisterHost(GetID());
585 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
586 switches::kDisableGpuShaderDiskCache)) {
587 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
588 base::Bind(&RemoveShaderInfo, GetID()));
592 void RenderProcessHostImpl::EnableSendQueue() {
593 is_initialized_ = false;
596 bool RenderProcessHostImpl::Init() {
597 // calling Init() more than once does nothing, this makes it more convenient
598 // for the view host which may not be sure in some cases
599 if (channel_)
600 return true;
602 base::CommandLine::StringType renderer_prefix;
603 // A command prefix is something prepended to the command line of the spawned
604 // process.
605 const base::CommandLine& browser_command_line =
606 *base::CommandLine::ForCurrentProcess();
607 renderer_prefix =
608 browser_command_line.GetSwitchValueNative(switches::kRendererCmdPrefix);
610 #if defined(OS_LINUX)
611 int flags = renderer_prefix.empty() ? ChildProcessHost::CHILD_ALLOW_SELF :
612 ChildProcessHost::CHILD_NORMAL;
613 #else
614 int flags = ChildProcessHost::CHILD_NORMAL;
615 #endif
617 // Find the renderer before creating the channel so if this fails early we
618 // return without creating the channel.
619 base::FilePath renderer_path = ChildProcessHost::GetChildPath(flags);
620 if (renderer_path.empty())
621 return false;
623 // Setup the IPC channel.
624 const std::string channel_id =
625 IPC::Channel::GenerateVerifiedChannelID(std::string());
626 channel_ = CreateChannelProxy(channel_id);
628 // Setup the Mojo channel.
629 mojo_application_host_->Init();
631 // Call the embedder first so that their IPC filters have priority.
632 GetContentClient()->browser()->RenderProcessWillLaunch(this);
634 CreateMessageFilters();
635 RegisterMojoServices();
637 if (run_renderer_in_process()) {
638 DCHECK(g_renderer_main_thread_factory);
639 // Crank up a thread and run the initialization there. With the way that
640 // messages flow between the browser and renderer, this thread is required
641 // to prevent a deadlock in single-process mode. Since the primordial
642 // thread in the renderer process runs the WebKit code and can sometimes
643 // make blocking calls to the UI thread (i.e. this thread), they need to run
644 // on separate threads.
645 in_process_renderer_.reset(
646 g_renderer_main_thread_factory(InProcessChildThreadParams(
647 channel_id, BrowserThread::UnsafeGetMessageLoopForThread(
648 BrowserThread::IO)->task_runner())));
650 base::Thread::Options options;
651 #if defined(OS_WIN) && !defined(OS_MACOSX)
652 // In-process plugins require this to be a UI message loop.
653 options.message_loop_type = base::MessageLoop::TYPE_UI;
654 #else
655 // We can't have multiple UI loops on Linux and Android, so we don't support
656 // in-process plugins.
657 options.message_loop_type = base::MessageLoop::TYPE_DEFAULT;
658 #endif
660 // As for execution sequence, this callback should have no any dependency
661 // on starting in-process-render-thread.
662 // So put it here to trigger ChannelMojo initialization earlier to enable
663 // in-process-render-thread using ChannelMojo there.
664 OnProcessLaunched(); // Fake a callback that the process is ready.
666 in_process_renderer_->StartWithOptions(options);
668 g_in_process_thread = in_process_renderer_->message_loop();
670 } else {
671 // Build command line for renderer. We call AppendRendererCommandLine()
672 // first so the process type argument will appear first.
673 base::CommandLine* cmd_line = new base::CommandLine(renderer_path);
674 if (!renderer_prefix.empty())
675 cmd_line->PrependWrapper(renderer_prefix);
676 AppendRendererCommandLine(cmd_line);
677 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id);
679 // Spawn the child process asynchronously to avoid blocking the UI thread.
680 // As long as there's no renderer prefix, we can use the zygote process
681 // at this stage.
682 child_process_launcher_.reset(new ChildProcessLauncher(
683 new RendererSandboxedProcessLauncherDelegate(channel_.get()),
684 cmd_line,
685 GetID(),
686 this));
688 fast_shutdown_started_ = false;
691 if (!gpu_observer_registered_) {
692 gpu_observer_registered_ = true;
693 ui::GpuSwitchingManager::GetInstance()->AddObserver(this);
696 power_monitor_broadcaster_.Init();
698 is_initialized_ = true;
699 init_time_ = base::TimeTicks::Now();
700 return true;
703 scoped_ptr<IPC::ChannelProxy> RenderProcessHostImpl::CreateChannelProxy(
704 const std::string& channel_id) {
705 scoped_refptr<base::SingleThreadTaskRunner> runner =
706 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO);
707 scoped_refptr<base::SequencedTaskRunner> mojo_task_runner =
708 BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::IO)
709 ->task_runner();
710 if (ShouldUseMojoChannel()) {
711 VLOG(1) << "Mojo Channel is enabled on host";
713 return IPC::ChannelProxy::Create(
714 IPC::ChannelMojo::CreateServerFactory(
715 mojo_task_runner, channel_id,
716 content::ChildProcessHost::GetAttachmentBroker()),
717 this, runner.get());
720 return IPC::ChannelProxy::Create(
721 channel_id, IPC::Channel::MODE_SERVER, this, runner.get(),
722 content::ChildProcessHost::GetAttachmentBroker());
725 void RenderProcessHostImpl::CreateMessageFilters() {
726 DCHECK_CURRENTLY_ON(BrowserThread::UI);
727 const base::CommandLine& browser_command_line =
728 *base::CommandLine::ForCurrentProcess();
729 AddFilter(new ResourceSchedulerFilter(GetID()));
730 MediaInternals* media_internals = MediaInternals::GetInstance();
731 media::AudioManager* audio_manager =
732 BrowserMainLoop::GetInstance()->audio_manager();
733 // Add BrowserPluginMessageFilter to ensure it gets the first stab at messages
734 // from guests.
735 scoped_refptr<BrowserPluginMessageFilter> bp_message_filter(
736 new BrowserPluginMessageFilter(GetID()));
737 AddFilter(bp_message_filter.get());
739 scoped_refptr<RenderMessageFilter> render_message_filter(
740 new RenderMessageFilter(
741 GetID(),
742 #if defined(ENABLE_PLUGINS)
743 PluginServiceImpl::GetInstance(),
744 #else
745 NULL,
746 #endif
747 GetBrowserContext(),
748 GetBrowserContext()->GetRequestContextForRenderProcess(GetID()),
749 widget_helper_.get(),
750 audio_manager,
751 media_internals,
752 storage_partition_impl_->GetDOMStorageContext()));
753 AddFilter(render_message_filter.get());
754 AddFilter(
755 new RenderFrameMessageFilter(GetID(), widget_helper_.get()));
756 BrowserContext* browser_context = GetBrowserContext();
757 ResourceContext* resource_context = browser_context->GetResourceContext();
759 scoped_refptr<net::URLRequestContextGetter> request_context(
760 browser_context->GetRequestContextForRenderProcess(GetID()));
761 scoped_refptr<net::URLRequestContextGetter> media_request_context(
762 browser_context->GetMediaRequestContextForRenderProcess(GetID()));
764 ResourceMessageFilter::GetContextsCallback get_contexts_callback(
765 base::Bind(&GetContexts, browser_context->GetResourceContext(),
766 request_context, media_request_context));
768 ResourceMessageFilter* resource_message_filter = new ResourceMessageFilter(
769 GetID(), PROCESS_TYPE_RENDERER,
770 storage_partition_impl_->GetAppCacheService(),
771 ChromeBlobStorageContext::GetFor(browser_context),
772 storage_partition_impl_->GetFileSystemContext(),
773 storage_partition_impl_->GetServiceWorkerContext(),
774 storage_partition_impl_->GetHostZoomLevelContext(),
775 get_contexts_callback);
777 AddFilter(resource_message_filter);
778 MediaStreamManager* media_stream_manager =
779 BrowserMainLoop::GetInstance()->media_stream_manager();
780 AddFilter(new AudioInputRendererHost(
781 GetID(),
782 audio_manager,
783 media_stream_manager,
784 AudioMirroringManager::GetInstance(),
785 BrowserMainLoop::GetInstance()->user_input_monitor()));
786 // The AudioRendererHost needs to be available for lookup, so it's
787 // stashed in a member variable.
788 audio_renderer_host_ = new AudioRendererHost(
789 GetID(),
790 audio_manager,
791 AudioMirroringManager::GetInstance(),
792 media_internals,
793 media_stream_manager,
794 browser_context->GetResourceContext()->GetMediaDeviceIDSalt());
795 AddFilter(audio_renderer_host_.get());
796 AddFilter(
797 new MidiHost(GetID(), BrowserMainLoop::GetInstance()->midi_manager()));
798 AddFilter(new VideoCaptureHost(media_stream_manager));
799 AddFilter(new AppCacheDispatcherHost(
800 storage_partition_impl_->GetAppCacheService(),
801 GetID()));
802 AddFilter(new ClipboardMessageFilter);
803 AddFilter(new DOMStorageMessageFilter(
804 storage_partition_impl_->GetDOMStorageContext()));
805 AddFilter(new IndexedDBDispatcherHost(
806 GetID(),
807 storage_partition_impl_->GetURLRequestContext(),
808 storage_partition_impl_->GetIndexedDBContext(),
809 ChromeBlobStorageContext::GetFor(browser_context)));
811 gpu_message_filter_ = new GpuMessageFilter(GetID(), widget_helper_.get());
812 AddFilter(gpu_message_filter_);
813 #if defined(ENABLE_WEBRTC)
814 AddFilter(new WebRTCIdentityServiceHost(
815 GetID(),
816 storage_partition_impl_->GetWebRTCIdentityStore(),
817 resource_context));
818 peer_connection_tracker_host_ = new PeerConnectionTrackerHost(GetID());
819 AddFilter(peer_connection_tracker_host_.get());
820 AddFilter(new MediaStreamDispatcherHost(
821 GetID(),
822 browser_context->GetResourceContext()->GetMediaDeviceIDSalt(),
823 media_stream_manager));
824 AddFilter(new MediaStreamTrackMetricsHost());
825 #endif
826 #if defined(ENABLE_PLUGINS)
827 AddFilter(new PepperRendererConnection(GetID()));
828 #endif
829 AddFilter(new SpeechRecognitionDispatcherHost(
830 GetID(), storage_partition_impl_->GetURLRequestContext()));
831 AddFilter(new FileAPIMessageFilter(
832 GetID(),
833 storage_partition_impl_->GetURLRequestContext(),
834 storage_partition_impl_->GetFileSystemContext(),
835 ChromeBlobStorageContext::GetFor(browser_context),
836 StreamContext::GetFor(browser_context)));
837 AddFilter(new FileUtilitiesMessageFilter(GetID()));
838 AddFilter(new MimeRegistryMessageFilter());
839 AddFilter(new DatabaseMessageFilter(
840 storage_partition_impl_->GetDatabaseTracker()));
841 #if defined(OS_MACOSX)
842 AddFilter(new TextInputClientMessageFilter(GetID()));
843 #elif defined(OS_WIN)
844 // The FontCacheDispatcher is required only when we're using GDI rendering.
845 // TODO(scottmg): pdf/ppapi still require the renderer to be able to precache
846 // GDI fonts (http://crbug.com/383227), even when using DirectWrite. This
847 // should eventually be if (!ShouldUseDirectWrite()) guarded.
848 channel_->AddFilter(new FontCacheDispatcher());
849 #elif defined(OS_ANDROID)
850 browser_demuxer_android_ = new BrowserDemuxerAndroid();
851 AddFilter(browser_demuxer_android_.get());
852 #endif
853 #if defined(ENABLE_BROWSER_CDMS)
854 AddFilter(new BrowserCdmManager(GetID(), NULL));
855 #endif
857 WebSocketDispatcherHost::GetRequestContextCallback
858 websocket_request_context_callback(
859 base::Bind(&GetRequestContext, request_context,
860 media_request_context, RESOURCE_TYPE_SUB_RESOURCE));
862 AddFilter(
863 new WebSocketDispatcherHost(GetID(), websocket_request_context_callback));
865 message_port_message_filter_ = new MessagePortMessageFilter(
866 base::Bind(&RenderWidgetHelper::GetNextRoutingID,
867 base::Unretained(widget_helper_.get())));
868 AddFilter(message_port_message_filter_.get());
870 scoped_refptr<CacheStorageDispatcherHost> cache_storage_filter =
871 new CacheStorageDispatcherHost();
872 cache_storage_filter->Init(storage_partition_impl_->GetCacheStorageContext());
873 AddFilter(cache_storage_filter.get());
875 scoped_refptr<ServiceWorkerDispatcherHost> service_worker_filter =
876 new ServiceWorkerDispatcherHost(
877 GetID(), message_port_message_filter_.get(), resource_context);
878 service_worker_filter->Init(
879 storage_partition_impl_->GetServiceWorkerContext());
880 AddFilter(service_worker_filter.get());
882 AddFilter(new SharedWorkerMessageFilter(
883 GetID(),
884 resource_context,
885 WorkerStoragePartition(
886 storage_partition_impl_->GetURLRequestContext(),
887 storage_partition_impl_->GetMediaURLRequestContext(),
888 storage_partition_impl_->GetAppCacheService(),
889 storage_partition_impl_->GetQuotaManager(),
890 storage_partition_impl_->GetFileSystemContext(),
891 storage_partition_impl_->GetDatabaseTracker(),
892 storage_partition_impl_->GetIndexedDBContext(),
893 storage_partition_impl_->GetServiceWorkerContext()),
894 message_port_message_filter_.get()));
896 #if defined(ENABLE_WEBRTC)
897 p2p_socket_dispatcher_host_ = new P2PSocketDispatcherHost(
898 resource_context,
899 browser_context->GetRequestContextForRenderProcess(GetID()));
900 AddFilter(p2p_socket_dispatcher_host_.get());
901 #endif
903 AddFilter(new TraceMessageFilter(GetID()));
904 AddFilter(new ResolveProxyMsgHelper(
905 browser_context->GetRequestContextForRenderProcess(GetID())));
906 AddFilter(new QuotaDispatcherHost(
907 GetID(),
908 storage_partition_impl_->GetQuotaManager(),
909 GetContentClient()->browser()->CreateQuotaPermissionContext()));
911 notification_message_filter_ = new NotificationMessageFilter(
912 GetID(),
913 storage_partition_impl_->GetPlatformNotificationContext(),
914 resource_context,
915 browser_context);
916 AddFilter(notification_message_filter_.get());
918 AddFilter(new GamepadBrowserMessageFilter());
919 AddFilter(new DeviceLightMessageFilter());
920 AddFilter(new DeviceMotionMessageFilter());
921 AddFilter(new DeviceOrientationMessageFilter());
922 AddFilter(new ProfilerMessageFilter(PROCESS_TYPE_RENDERER));
923 AddFilter(new HistogramMessageFilter());
924 #if defined(USE_TCMALLOC) && (defined(OS_LINUX) || defined(OS_ANDROID))
925 if (browser_command_line.HasSwitch(switches::kEnableMemoryBenchmarking))
926 AddFilter(new MemoryBenchmarkMessageFilter());
927 #endif
928 AddFilter(new PushMessagingMessageFilter(
929 GetID(), storage_partition_impl_->GetServiceWorkerContext()));
930 #if defined(OS_ANDROID)
931 AddFilter(new ScreenOrientationMessageFilterAndroid());
932 #endif
933 AddFilter(new GeofencingDispatcherHost(
934 storage_partition_impl_->GetGeofencingManager()));
935 if (browser_command_line.HasSwitch(switches::kEnableWebBluetooth)) {
936 bluetooth_dispatcher_host_ = new BluetoothDispatcherHost(GetID());
937 AddFilter(bluetooth_dispatcher_host_.get());
941 void RenderProcessHostImpl::RegisterMojoServices() {
942 mojo_application_host_->service_registry()->AddService(
943 base::Bind(&device::BatteryMonitorImpl::Create));
945 mojo_application_host_->service_registry()->AddService(
946 base::Bind(&device::VibrationManagerImpl::Create));
948 mojo_application_host_->service_registry()->AddService(
949 base::Bind(&PermissionServiceContext::CreateService,
950 base::Unretained(permission_service_context_.get())));
952 mojo_application_host_->service_registry()->AddService(base::Bind(
953 &content::BackgroundSyncServiceImpl::Create,
954 base::Unretained(storage_partition_impl_->GetBackgroundSyncContext())));
956 mojo_application_host_->service_registry()->AddService(base::Bind(
957 &content::ServicePortServiceImpl::Create,
958 make_scoped_refptr(storage_partition_impl_->GetNavigatorConnectContext()),
959 message_port_message_filter_));
961 #if defined(OS_ANDROID)
962 ServiceRegistrarAndroid::RegisterProcessHostServices(
963 mojo_application_host_->service_registry_android());
964 #endif
966 GetContentClient()->browser()->RegisterRenderProcessMojoServices(
967 mojo_application_host_->service_registry());
970 int RenderProcessHostImpl::GetNextRoutingID() {
971 return widget_helper_->GetNextRoutingID();
974 void RenderProcessHostImpl::ResumeDeferredNavigation(
975 const GlobalRequestID& request_id) {
976 widget_helper_->ResumeDeferredNavigation(request_id);
979 void RenderProcessHostImpl::NotifyTimezoneChange(const std::string& zone_id) {
980 Send(new ViewMsg_TimezoneChange(zone_id));
983 ServiceRegistry* RenderProcessHostImpl::GetServiceRegistry() {
984 DCHECK(mojo_application_host_);
985 return mojo_application_host_->service_registry();
988 const base::TimeTicks& RenderProcessHostImpl::GetInitTimeForNavigationMetrics()
989 const {
990 return init_time_;
993 bool RenderProcessHostImpl::SubscribeUniformEnabled() const {
994 return subscribe_uniform_enabled_;
997 void RenderProcessHostImpl::OnAddSubscription(unsigned int target) {
998 DCHECK(subscribe_uniform_enabled_);
999 subscription_set_.insert(target);
1000 const gpu::ValueState* state = pending_valuebuffer_state_->GetState(target);
1001 if (state) {
1002 SendUpdateValueState(target, *state);
1006 void RenderProcessHostImpl::OnRemoveSubscription(unsigned int target) {
1007 DCHECK(subscribe_uniform_enabled_);
1008 subscription_set_.erase(target);
1011 void RenderProcessHostImpl::SendUpdateValueState(unsigned int target,
1012 const gpu::ValueState& state) {
1013 DCHECK(subscribe_uniform_enabled_);
1014 if (subscription_set_.find(target) != subscription_set_.end()) {
1015 GpuProcessHost::SendOnIO(
1016 GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
1017 CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH,
1018 new GpuMsg_UpdateValueState(id_, target, state));
1019 } else {
1020 // Store the ValueState locally in case a Valuebuffer subscribes to it later
1021 pending_valuebuffer_state_->UpdateState(target, state);
1025 #if defined(ENABLE_BROWSER_CDMS)
1026 media::BrowserCdm* RenderProcessHostImpl::GetBrowserCdm(int render_frame_id,
1027 int cdm_id) const {
1028 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1029 BrowserCdmManager* manager = BrowserCdmManager::FromProcess(GetID());
1030 if (!manager)
1031 return nullptr;
1032 return manager->GetCdm(render_frame_id, cdm_id);
1034 #endif
1036 void RenderProcessHostImpl::AddRoute(
1037 int32 routing_id,
1038 IPC::Listener* listener) {
1039 CHECK(!listeners_.Lookup(routing_id))
1040 << "Found Routing ID Conflict: " << routing_id;
1041 listeners_.AddWithID(listener, routing_id);
1044 void RenderProcessHostImpl::RemoveRoute(int32 routing_id) {
1045 DCHECK(listeners_.Lookup(routing_id) != NULL);
1046 listeners_.Remove(routing_id);
1048 // Keep the one renderer thread around forever in single process mode.
1049 if (!run_renderer_in_process())
1050 Cleanup();
1053 void RenderProcessHostImpl::AddObserver(RenderProcessHostObserver* observer) {
1054 observers_.AddObserver(observer);
1057 void RenderProcessHostImpl::RemoveObserver(
1058 RenderProcessHostObserver* observer) {
1059 observers_.RemoveObserver(observer);
1062 void RenderProcessHostImpl::ShutdownForBadMessage() {
1063 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
1064 if (command_line->HasSwitch(switches::kDisableKillAfterBadIPC))
1065 return;
1067 if (run_renderer_in_process()) {
1068 // In single process mode it is better if we don't suicide but just
1069 // crash.
1070 CHECK(false);
1072 // We kill the renderer but don't include a NOTREACHED, because we want the
1073 // browser to try to survive when it gets illegal messages from the renderer.
1074 Shutdown(RESULT_CODE_KILLED_BAD_MESSAGE, false);
1077 void RenderProcessHostImpl::WidgetRestored() {
1078 // Verify we were properly backgrounded.
1079 DCHECK_EQ(backgrounded_, (visible_widgets_ == 0));
1080 visible_widgets_++;
1081 SetBackgrounded(false);
1084 void RenderProcessHostImpl::WidgetHidden() {
1085 // On startup, the browser will call Hide
1086 if (backgrounded_)
1087 return;
1089 DCHECK_EQ(backgrounded_, (visible_widgets_ == 0));
1090 visible_widgets_--;
1091 DCHECK_GE(visible_widgets_, 0);
1092 if (visible_widgets_ == 0) {
1093 DCHECK(!backgrounded_);
1094 SetBackgrounded(true);
1098 int RenderProcessHostImpl::VisibleWidgetCount() const {
1099 return visible_widgets_;
1102 bool RenderProcessHostImpl::IsForGuestsOnly() const {
1103 return is_for_guests_only_;
1106 StoragePartition* RenderProcessHostImpl::GetStoragePartition() const {
1107 return storage_partition_impl_;
1110 static void AppendCompositorCommandLineFlags(base::CommandLine* command_line) {
1111 if (IsPropertyTreeVerificationEnabled())
1112 command_line->AppendSwitch(cc::switches::kEnablePropertyTreeVerification);
1114 if (IsDelegatedRendererEnabled())
1115 command_line->AppendSwitch(switches::kEnableDelegatedRenderer);
1117 command_line->AppendSwitchASCII(
1118 switches::kNumRasterThreads,
1119 base::IntToString(NumberOfRendererRasterThreads()));
1121 if (IsGpuRasterizationEnabled())
1122 command_line->AppendSwitch(switches::kEnableGpuRasterization);
1124 int msaa_sample_count = GpuRasterizationMSAASampleCount();
1125 if (msaa_sample_count > 0) {
1126 command_line->AppendSwitchASCII(
1127 switches::kGpuRasterizationMSAASampleCount,
1128 base::IntToString(msaa_sample_count));
1131 DCHECK_IMPLIES(IsZeroCopyUploadEnabled(), !IsOneCopyUploadEnabled());
1132 DCHECK_IMPLIES(IsOneCopyUploadEnabled(), !IsZeroCopyUploadEnabled());
1133 if (IsZeroCopyUploadEnabled())
1134 command_line->AppendSwitch(switches::kEnableZeroCopy);
1135 if (!IsOneCopyUploadEnabled())
1136 command_line->AppendSwitch(switches::kDisableOneCopy);
1138 if (IsForceGpuRasterizationEnabled())
1139 command_line->AppendSwitch(switches::kForceGpuRasterization);
1141 command_line->AppendSwitchASCII(
1142 switches::kContentImageTextureTarget,
1143 base::UintToString(
1144 // TODO(reveman): We currently assume that the compositor will use
1145 // BGRA_8888 if it's able to, and RGBA_8888 otherwise. Since we don't
1146 // know what it will use we hardcode BGRA_8888 here for now. We should
1147 // instead move decisions about GpuMemoryBuffer format to the browser
1148 // embedder so we know it here, and pass that decision to the
1149 // compositor for each usage.
1150 // crbug.com/490362
1151 BrowserGpuMemoryBufferManager::GetImageTextureTarget(
1152 gfx::GpuMemoryBuffer::BGRA_8888,
1153 // TODO(danakj): When one-copy supports partial update, change
1154 // this usage to PERSISTENT_MAP for one-copy.
1155 gfx::GpuMemoryBuffer::MAP)));
1157 command_line->AppendSwitchASCII(
1158 switches::kVideoImageTextureTarget,
1159 base::UintToString(BrowserGpuMemoryBufferManager::GetImageTextureTarget(
1160 gfx::GpuMemoryBuffer::R_8, gfx::GpuMemoryBuffer::MAP)));
1162 // Appending disable-gpu-feature switches due to software rendering list.
1163 GpuDataManagerImpl* gpu_data_manager = GpuDataManagerImpl::GetInstance();
1164 DCHECK(gpu_data_manager);
1165 gpu_data_manager->AppendRendererCommandLine(command_line);
1168 void RenderProcessHostImpl::AppendRendererCommandLine(
1169 base::CommandLine* command_line) const {
1170 // Pass the process type first, so it shows first in process listings.
1171 command_line->AppendSwitchASCII(switches::kProcessType,
1172 switches::kRendererProcess);
1174 // Now send any options from our own command line we want to propagate.
1175 const base::CommandLine& browser_command_line =
1176 *base::CommandLine::ForCurrentProcess();
1177 PropagateBrowserCommandLineToRenderer(browser_command_line, command_line);
1179 // Pass on the browser locale.
1180 const std::string locale =
1181 GetContentClient()->browser()->GetApplicationLocale();
1182 command_line->AppendSwitchASCII(switches::kLang, locale);
1184 // If we run base::FieldTrials, we want to pass to their state to the
1185 // renderer so that it can act in accordance with each state, or record
1186 // histograms relating to the base::FieldTrial states.
1187 std::string field_trial_states;
1188 base::FieldTrialList::AllStatesToString(&field_trial_states);
1189 if (!field_trial_states.empty()) {
1190 command_line->AppendSwitchASCII(switches::kForceFieldTrials,
1191 field_trial_states);
1194 GetContentClient()->browser()->AppendExtraCommandLineSwitches(
1195 command_line, GetID());
1197 if (IsPinchToZoomEnabled())
1198 command_line->AppendSwitch(switches::kEnablePinch);
1200 #if defined(OS_WIN)
1201 command_line->AppendSwitchASCII(switches::kDeviceScaleFactor,
1202 base::DoubleToString(gfx::GetDPIScale()));
1203 #endif
1205 AppendCompositorCommandLineFlags(command_line);
1208 void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
1209 const base::CommandLine& browser_cmd,
1210 base::CommandLine* renderer_cmd) const {
1211 // Propagate the following switches to the renderer command line (along
1212 // with any associated values) if present in the browser command line.
1213 static const char* const kSwitchNames[] = {
1214 switches::kAllowLoopbackInPeerConnection,
1215 switches::kAudioBufferSize,
1216 switches::kBlinkPlatformLogChannels,
1217 switches::kBlinkSettings,
1218 switches::kDefaultTileWidth,
1219 switches::kDefaultTileHeight,
1220 switches::kDisable3DAPIs,
1221 switches::kDisableAcceleratedJpegDecoding,
1222 switches::kDisableAcceleratedVideoDecode,
1223 switches::kDisableBlinkFeatures,
1224 switches::kDisableBreakpad,
1225 switches::kDisablePreferCompositingToLCDText,
1226 switches::kDisableDatabases,
1227 switches::kDisableDelayAgnosticAec,
1228 switches::kDisableDirectNPAPIRequests,
1229 switches::kDisableDisplayList2dCanvas,
1230 switches::kDisableDistanceFieldText,
1231 switches::kDisableEncryptedMedia,
1232 switches::kDisableFileSystem,
1233 switches::kDisableGpuCompositing,
1234 switches::kDisableGpuVsync,
1235 switches::kDisableLowResTiling,
1236 switches::kDisableHistogramCustomizer,
1237 switches::kDisableIconNtp,
1238 switches::kDisableLCDText,
1239 switches::kDisableLocalStorage,
1240 switches::kDisableLogging,
1241 switches::kDisableMediaSource,
1242 switches::kDisableMojoChannel,
1243 switches::kDisableNewVideoRenderer,
1244 switches::kDisableNotifications,
1245 switches::kDisableOverlayScrollbar,
1246 switches::kDisablePermissionsAPI,
1247 switches::kDisablePinch,
1248 switches::kDisablePrefixedEncryptedMedia,
1249 switches::kDisableSeccompFilterSandbox,
1250 switches::kDisableSharedWorkers,
1251 switches::kDisableSlimmingPaint,
1252 switches::kDisableSpeechAPI,
1253 switches::kDisableSVG1DOM,
1254 switches::kDisableThreadedCompositing,
1255 switches::kDisableThreadedScrolling,
1256 switches::kDisableTouchAdjustment,
1257 switches::kDisableTouchDragDrop,
1258 switches::kDisableTouchEditing,
1259 switches::kDisableV8IdleTasks,
1260 switches::kDomAutomationController,
1261 switches::kEnableBleedingEdgeRenderingFastPaths,
1262 switches::kEnableBlinkFeatures,
1263 switches::kEnableBrowserSideNavigation,
1264 switches::kEnableCompositorAnimationTimelines,
1265 switches::kEnableCredentialManagerAPI,
1266 switches::kEnableDelayAgnosticAec,
1267 switches::kEnableDisplayList2dCanvas,
1268 switches::kEnableDistanceFieldText,
1269 switches::kEnableExperimentalCanvasFeatures,
1270 switches::kEnableExperimentalWebPlatformFeatures,
1271 switches::kEnableGPUClientLogging,
1272 switches::kEnableGpuClientTracing,
1273 switches::kEnableGPUServiceLogging,
1274 switches::kEnableIconNtp,
1275 switches::kEnableLinkDisambiguationPopup,
1276 switches::kEnableLowResTiling,
1277 switches::kEnableInbandTextTracks,
1278 switches::kEnableLCDText,
1279 switches::kEnableLogging,
1280 switches::kEnableMemoryBenchmarking,
1281 switches::kEnableNetworkInformation,
1282 switches::kEnableOverlayFullscreenVideo,
1283 switches::kEnableOverlayScrollbar,
1284 switches::kEnablePinch,
1285 switches::kEnablePluginPlaceholderTesting,
1286 switches::kEnablePreciseMemoryInfo,
1287 switches::kEnablePreferCompositingToLCDText,
1288 switches::kEnablePushMessagePayload,
1289 switches::kEnableRendererMojoChannel,
1290 switches::kEnableRTCSmoothnessAlgorithm,
1291 switches::kEnableSeccompFilterSandbox,
1292 switches::kEnableSkiaBenchmarking,
1293 switches::kEnableSlimmingPaint,
1294 switches::kEnableSmoothScrolling,
1295 switches::kEnableStaleWhileRevalidate,
1296 switches::kEnableStatsTable,
1297 switches::kEnableThreadedCompositing,
1298 switches::kEnableTouchDragDrop,
1299 switches::kEnableTouchEditing,
1300 switches::kEnableUnsafeES3APIs,
1301 switches::kEnableViewport,
1302 switches::kEnableViewportMeta,
1303 switches::kInvertViewportScrollOrder,
1304 switches::kEnableVtune,
1305 switches::kEnableWebBluetooth,
1306 switches::kEnableWebGLDraftExtensions,
1307 switches::kEnableWebGLImageChromium,
1308 switches::kEnableWebVR,
1309 switches::kExplicitlyAllowedPorts,
1310 switches::kForceDeviceScaleFactor,
1311 switches::kForceDisplayList2dCanvas,
1312 switches::kFullMemoryCrashReport,
1313 switches::kIPCConnectionTimeout,
1314 switches::kJavaScriptFlags,
1315 switches::kLoggingLevel,
1316 switches::kMainFrameResizesAreOrientationChanges,
1317 switches::kMaxUntiledLayerWidth,
1318 switches::kMaxUntiledLayerHeight,
1319 switches::kMemoryMetrics,
1320 switches::kNoReferrers,
1321 switches::kNoSandbox,
1322 switches::kOverridePluginPowerSaverForTesting,
1323 switches::kPpapiInProcess,
1324 switches::kProfilerTiming,
1325 switches::kReducedReferrerGranularity,
1326 switches::kReduceSecurityForTesting,
1327 switches::kRegisterPepperPlugins,
1328 switches::kRendererStartupDialog,
1329 switches::kRootLayerScrolls,
1330 switches::kShowPaintRects,
1331 switches::kSitePerProcess,
1332 switches::kStatsCollectionController,
1333 switches::kTestType,
1334 switches::kTouchEvents,
1335 switches::kTouchTextSelectionStrategy,
1336 switches::kTraceToConsole,
1337 // This flag needs to be propagated to the renderer process for
1338 // --in-process-webgl.
1339 switches::kUseGL,
1340 switches::kUseMobileUserAgent,
1341 switches::kUseNormalPriorityForTileTaskWorkerThreads,
1342 switches::kV,
1343 switches::kVideoThreads,
1344 switches::kVideoUnderflowThresholdMs,
1345 switches::kVModule,
1346 // Please keep these in alphabetical order. Compositor switches here should
1347 // also be added to chrome/browser/chromeos/login/chrome_restart_request.cc.
1348 cc::switches::kCompositeToMailbox,
1349 cc::switches::kDisableCompositedAntialiasing,
1350 cc::switches::kDisableMainFrameBeforeActivation,
1351 cc::switches::kDisableThreadedAnimation,
1352 cc::switches::kEnableBeginFrameScheduling,
1353 cc::switches::kEnableGpuBenchmarking,
1354 cc::switches::kEnableMainFrameBeforeActivation,
1355 cc::switches::kMaxUnusedResourceMemoryUsagePercentage,
1356 cc::switches::kShowCompositedLayerBorders,
1357 cc::switches::kShowFPSCounter,
1358 cc::switches::kShowLayerAnimationBounds,
1359 cc::switches::kShowPropertyChangedRects,
1360 cc::switches::kShowReplicaScreenSpaceRects,
1361 cc::switches::kShowScreenSpaceRects,
1362 cc::switches::kShowSurfaceDamageRects,
1363 cc::switches::kSlowDownRasterScaleFactor,
1364 cc::switches::kStrictLayerPropertyChangeChecking,
1365 cc::switches::kTopControlsHideThreshold,
1366 cc::switches::kTopControlsShowThreshold,
1368 scheduler::switches::kDisableBlinkScheduler,
1370 #if defined(ENABLE_PLUGINS)
1371 switches::kEnablePepperTesting,
1372 #endif
1373 #if defined(ENABLE_WEBRTC)
1374 switches::kDisableWebRtcHWDecoding,
1375 switches::kDisableWebRtcHWEncoding,
1376 switches::kEnableWebRtcDtls12,
1377 switches::kEnableWebRtcHWH264Encoding,
1378 switches::kEnableWebRtcStunOrigin,
1379 switches::kWebRtcMaxCaptureFramerate,
1380 #endif
1381 switches::kEnableLowEndDeviceMode,
1382 switches::kDisableLowEndDeviceMode,
1383 #if defined(OS_ANDROID)
1384 switches::kDisableGestureRequirementForMediaPlayback,
1385 switches::kDisableWebRTC,
1386 switches::kDisableWebAudio,
1387 switches::kRendererWaitForJavaDebugger,
1388 #endif
1389 #if defined(OS_MACOSX)
1390 // Allow this to be set when invoking the browser and relayed along.
1391 switches::kEnableSandboxLogging,
1392 #endif
1393 #if defined(OS_WIN)
1394 switches::kDisableDirectWrite,
1395 switches::kDisableWin32kRendererLockDown,
1396 switches::kTraceExportEventsToETW,
1397 #endif
1398 #if defined(OS_CHROMEOS)
1399 switches::kDisableVaapiAcceleratedVideoEncode,
1400 #endif
1402 renderer_cmd->CopySwitchesFrom(browser_cmd, kSwitchNames,
1403 arraysize(kSwitchNames));
1405 if (browser_cmd.HasSwitch(switches::kTraceStartup) &&
1406 BrowserMainLoop::GetInstance()->is_tracing_startup()) {
1407 // Pass kTraceStartup switch to renderer only if startup tracing has not
1408 // finished.
1409 renderer_cmd->AppendSwitchASCII(
1410 switches::kTraceStartup,
1411 browser_cmd.GetSwitchValueASCII(switches::kTraceStartup));
1414 #if defined(ENABLE_WEBRTC)
1415 // Only run the Stun trials in the first renderer.
1416 if (!has_done_stun_trials &&
1417 browser_cmd.HasSwitch(switches::kWebRtcStunProbeTrialParameter)) {
1418 has_done_stun_trials = true;
1419 renderer_cmd->AppendSwitchASCII(
1420 switches::kWebRtcStunProbeTrialParameter,
1421 browser_cmd.GetSwitchValueASCII(
1422 switches::kWebRtcStunProbeTrialParameter));
1424 #endif
1426 // Disable databases in incognito mode.
1427 if (GetBrowserContext()->IsOffTheRecord() &&
1428 !browser_cmd.HasSwitch(switches::kDisableDatabases)) {
1429 renderer_cmd->AppendSwitch(switches::kDisableDatabases);
1432 // Add kWaitForDebugger to let renderer process wait for a debugger.
1433 if (browser_cmd.HasSwitch(switches::kWaitForDebuggerChildren)) {
1434 // Look to pass-on the kWaitForDebugger flag.
1435 std::string value =
1436 browser_cmd.GetSwitchValueASCII(switches::kWaitForDebuggerChildren);
1437 if (value.empty() || value == switches::kRendererProcess) {
1438 renderer_cmd->AppendSwitch(switches::kWaitForDebugger);
1443 base::ProcessHandle RenderProcessHostImpl::GetHandle() const {
1444 if (run_renderer_in_process())
1445 return base::GetCurrentProcessHandle();
1447 if (!child_process_launcher_.get() || child_process_launcher_->IsStarting())
1448 return base::kNullProcessHandle;
1450 return child_process_launcher_->GetProcess().Handle();
1453 bool RenderProcessHostImpl::Shutdown(int exit_code, bool wait) {
1454 if (run_renderer_in_process())
1455 return false; // Single process mode never shuts down the renderer.
1457 #if defined(OS_ANDROID)
1458 // Android requires a different approach for killing.
1459 StopChildProcess(GetHandle());
1460 return true;
1461 #else
1462 if (!child_process_launcher_.get() || child_process_launcher_->IsStarting())
1463 return false;
1465 return child_process_launcher_->GetProcess().Terminate(exit_code, wait);
1466 #endif
1469 bool RenderProcessHostImpl::FastShutdownIfPossible() {
1470 if (run_renderer_in_process())
1471 return false; // Single process mode never shuts down the renderer.
1473 if (!GetContentClient()->browser()->IsFastShutdownPossible())
1474 return false;
1476 if (!child_process_launcher_.get() ||
1477 child_process_launcher_->IsStarting() ||
1478 !GetHandle())
1479 return false; // Render process hasn't started or is probably crashed.
1481 // Test if there's an unload listener.
1482 // NOTE: It's possible that an onunload listener may be installed
1483 // while we're shutting down, so there's a small race here. Given that
1484 // the window is small, it's unlikely that the web page has much
1485 // state that will be lost by not calling its unload handlers properly.
1486 if (!SuddenTerminationAllowed())
1487 return false;
1489 if (worker_ref_count_ != 0) {
1490 if (survive_for_worker_start_time_.is_null())
1491 survive_for_worker_start_time_ = base::TimeTicks::Now();
1492 return false;
1495 // Set this before ProcessDied() so observers can tell if the render process
1496 // died due to fast shutdown versus another cause.
1497 fast_shutdown_started_ = true;
1499 ProcessDied(false /* already_dead */, nullptr);
1500 return true;
1503 bool RenderProcessHostImpl::Send(IPC::Message* msg) {
1504 TRACE_EVENT0("renderer_host", "RenderProcessHostImpl::Send");
1505 if (!channel_) {
1506 if (!is_initialized_) {
1507 queued_messages_.push(msg);
1508 return true;
1509 } else {
1510 delete msg;
1511 return false;
1515 if (child_process_launcher_.get() && child_process_launcher_->IsStarting()) {
1516 queued_messages_.push(msg);
1517 return true;
1520 return channel_->Send(msg);
1523 bool RenderProcessHostImpl::OnMessageReceived(const IPC::Message& msg) {
1524 // If we're about to be deleted, or have initiated the fast shutdown sequence,
1525 // we ignore incoming messages.
1527 if (deleting_soon_ || fast_shutdown_started_)
1528 return false;
1530 mark_child_process_activity_time();
1531 if (msg.routing_id() == MSG_ROUTING_CONTROL) {
1532 // Dispatch control messages.
1533 IPC_BEGIN_MESSAGE_MAP(RenderProcessHostImpl, msg)
1534 IPC_MESSAGE_HANDLER(ChildProcessHostMsg_ShutdownRequest,
1535 OnShutdownRequest)
1536 IPC_MESSAGE_HANDLER(ViewHostMsg_SuddenTerminationChanged,
1537 SuddenTerminationChanged)
1538 IPC_MESSAGE_HANDLER(ViewHostMsg_UserMetricsRecordAction,
1539 OnUserMetricsRecordAction)
1540 IPC_MESSAGE_HANDLER(ViewHostMsg_SavedPageAsMHTML, OnSavedPageAsMHTML)
1541 IPC_MESSAGE_HANDLER(ViewHostMsg_Close_ACK, OnCloseACK)
1542 #if defined(ENABLE_WEBRTC)
1543 IPC_MESSAGE_HANDLER(AecDumpMsg_RegisterAecDumpConsumer,
1544 OnRegisterAecDumpConsumer)
1545 IPC_MESSAGE_HANDLER(AecDumpMsg_UnregisterAecDumpConsumer,
1546 OnUnregisterAecDumpConsumer)
1547 #endif
1548 // Adding single handlers for your service here is fine, but once your
1549 // service needs more than one handler, please extract them into a new
1550 // message filter and add that filter to CreateMessageFilters().
1551 IPC_END_MESSAGE_MAP()
1553 return true;
1556 // Dispatch incoming messages to the appropriate IPC::Listener.
1557 IPC::Listener* listener = listeners_.Lookup(msg.routing_id());
1558 if (!listener) {
1559 if (msg.is_sync()) {
1560 // The listener has gone away, so we must respond or else the caller will
1561 // hang waiting for a reply.
1562 IPC::Message* reply = IPC::SyncMessage::GenerateReply(&msg);
1563 reply->set_reply_error();
1564 Send(reply);
1566 return true;
1568 return listener->OnMessageReceived(msg);
1571 void RenderProcessHostImpl::OnChannelConnected(int32 peer_pid) {
1572 #if defined(IPC_MESSAGE_LOG_ENABLED)
1573 Send(new ChildProcessMsg_SetIPCLoggingEnabled(
1574 IPC::Logging::GetInstance()->Enabled()));
1575 #endif
1577 tracked_objects::ThreadData::Status status =
1578 tracked_objects::ThreadData::status();
1579 Send(new ChildProcessMsg_SetProfilerStatus(status));
1581 #if defined(OS_MACOSX) && !defined(OS_IOS)
1582 io_surface_manager_token_ =
1583 BrowserIOSurfaceManager::GetInstance()->GenerateChildProcessToken(
1584 GetID());
1585 Send(new ChildProcessMsg_SetIOSurfaceManagerToken(io_surface_manager_token_));
1586 #endif
1589 void RenderProcessHostImpl::OnChannelError() {
1590 ProcessDied(true /* already_dead */, nullptr);
1593 void RenderProcessHostImpl::OnBadMessageReceived(const IPC::Message& message) {
1594 // Message de-serialization failed. We consider this a capital crime. Kill the
1595 // renderer if we have one.
1596 LOG(ERROR) << "bad message " << message.type() << " terminating renderer.";
1597 BrowserChildProcessHostImpl::HistogramBadMessageTerminated(
1598 PROCESS_TYPE_RENDERER);
1600 // Create a memory dump. This will contain enough stack frames to work out
1601 // what the bad message was.
1602 base::debug::DumpWithoutCrashing();
1604 bad_message::ReceivedBadMessage(this,
1605 bad_message::RPH_DESERIALIZATION_FAILED);
1608 BrowserContext* RenderProcessHostImpl::GetBrowserContext() const {
1609 return browser_context_;
1612 bool RenderProcessHostImpl::InSameStoragePartition(
1613 StoragePartition* partition) const {
1614 return storage_partition_impl_ == partition;
1617 int RenderProcessHostImpl::GetID() const {
1618 return id_;
1621 bool RenderProcessHostImpl::HasConnection() const {
1622 return channel_.get() != NULL;
1625 void RenderProcessHostImpl::SetIgnoreInputEvents(bool ignore_input_events) {
1626 ignore_input_events_ = ignore_input_events;
1629 bool RenderProcessHostImpl::IgnoreInputEvents() const {
1630 return ignore_input_events_;
1633 void RenderProcessHostImpl::Cleanup() {
1634 // If within_process_died_observer_ is true, one of our observers performed an
1635 // action that caused us to die (e.g. http://crbug.com/339504). Therefore,
1636 // delay the destruction until all of the observer callbacks have been made,
1637 // and guarantee that the RenderProcessHostDestroyed observer callback is
1638 // always the last callback fired.
1639 if (within_process_died_observer_) {
1640 delayed_cleanup_needed_ = true;
1641 return;
1643 delayed_cleanup_needed_ = false;
1645 // Records the time when the process starts surviving for workers for UMA.
1646 if (listeners_.IsEmpty() && worker_ref_count_ > 0 &&
1647 survive_for_worker_start_time_.is_null()) {
1648 survive_for_worker_start_time_ = base::TimeTicks::Now();
1651 // When there are no other owners of this object, we can delete ourselves.
1652 if (listeners_.IsEmpty() && worker_ref_count_ == 0) {
1653 if (!survive_for_worker_start_time_.is_null()) {
1654 UMA_HISTOGRAM_LONG_TIMES(
1655 "SharedWorker.RendererSurviveForWorkerTime",
1656 base::TimeTicks::Now() - survive_for_worker_start_time_);
1659 if (max_worker_count_ > 0) {
1660 // Record the max number of workers (SharedWorker or ServiceWorker)
1661 // that are simultaneously hosted in this renderer process.
1662 UMA_HISTOGRAM_COUNTS("Render.Workers.MaxWorkerCountInRendererProcess",
1663 max_worker_count_);
1666 // We cannot clean up twice; if this fails, there is an issue with our
1667 // control flow.
1668 DCHECK(!deleting_soon_);
1670 DCHECK_EQ(0, pending_views_);
1671 FOR_EACH_OBSERVER(RenderProcessHostObserver,
1672 observers_,
1673 RenderProcessHostDestroyed(this));
1674 NotificationService::current()->Notify(
1675 NOTIFICATION_RENDERER_PROCESS_TERMINATED,
1676 Source<RenderProcessHost>(this),
1677 NotificationService::NoDetails());
1679 #ifndef NDEBUG
1680 is_self_deleted_ = true;
1681 #endif
1682 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
1683 deleting_soon_ = true;
1684 // It's important not to wait for the DeleteTask to delete the channel
1685 // proxy. Kill it off now. That way, in case the profile is going away, the
1686 // rest of the objects attached to this RenderProcessHost start going
1687 // away first, since deleting the channel proxy will post a
1688 // OnChannelClosed() to IPC::ChannelProxy::Context on the IO thread.
1689 channel_.reset();
1691 // The following members should be cleared in ProcessDied() as well!
1692 gpu_message_filter_ = NULL;
1693 message_port_message_filter_ = NULL;
1695 RemoveUserData(kSessionStorageHolderKey);
1697 // Remove ourself from the list of renderer processes so that we can't be
1698 // reused in between now and when the Delete task runs.
1699 UnregisterHost(GetID());
1701 #if defined(OS_MACOSX) && !defined(OS_IOS)
1702 if (!io_surface_manager_token_.IsZero()) {
1703 BrowserIOSurfaceManager::GetInstance()->InvalidateChildProcessToken(
1704 io_surface_manager_token_);
1705 io_surface_manager_token_.SetZero();
1707 #endif
1712 void RenderProcessHostImpl::AddPendingView() {
1713 pending_views_++;
1716 void RenderProcessHostImpl::RemovePendingView() {
1717 DCHECK(pending_views_);
1718 pending_views_--;
1721 void RenderProcessHostImpl::SetSuddenTerminationAllowed(bool enabled) {
1722 sudden_termination_allowed_ = enabled;
1725 bool RenderProcessHostImpl::SuddenTerminationAllowed() const {
1726 return sudden_termination_allowed_;
1729 base::TimeDelta RenderProcessHostImpl::GetChildProcessIdleTime() const {
1730 return base::TimeTicks::Now() - child_process_activity_time_;
1733 void RenderProcessHostImpl::ResumeRequestsForView(int route_id) {
1734 widget_helper_->ResumeRequestsForView(route_id);
1737 void RenderProcessHostImpl::FilterURL(bool empty_allowed, GURL* url) {
1738 FilterURL(this, empty_allowed, url);
1741 #if defined(ENABLE_WEBRTC)
1742 void RenderProcessHostImpl::EnableAecDump(const base::FilePath& file) {
1743 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1744 // Enable AEC dump for each registered consumer.
1745 for (std::vector<int>::iterator it = aec_dump_consumers_.begin();
1746 it != aec_dump_consumers_.end(); ++it) {
1747 EnableAecDumpForId(file, *it);
1751 void RenderProcessHostImpl::DisableAecDump() {
1752 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1753 // Posting on the FILE thread and then replying back on the UI thread is only
1754 // for avoiding races between enable and disable. Nothing is done on the FILE
1755 // thread.
1756 BrowserThread::PostTaskAndReply(
1757 BrowserThread::FILE, FROM_HERE,
1758 base::Bind(&DisableAecDumpOnFileThread),
1759 base::Bind(&RenderProcessHostImpl::SendDisableAecDumpToRenderer,
1760 weak_factory_.GetWeakPtr()));
1763 void RenderProcessHostImpl::SetWebRtcLogMessageCallback(
1764 base::Callback<void(const std::string&)> callback) {
1765 webrtc_log_message_callback_ = callback;
1768 RenderProcessHostImpl::WebRtcStopRtpDumpCallback
1769 RenderProcessHostImpl::StartRtpDump(
1770 bool incoming,
1771 bool outgoing,
1772 const WebRtcRtpPacketCallback& packet_callback) {
1773 if (!p2p_socket_dispatcher_host_.get())
1774 return WebRtcStopRtpDumpCallback();
1776 BrowserThread::PostTask(BrowserThread::IO,
1777 FROM_HERE,
1778 base::Bind(&P2PSocketDispatcherHost::StartRtpDump,
1779 p2p_socket_dispatcher_host_,
1780 incoming,
1781 outgoing,
1782 packet_callback));
1784 if (stop_rtp_dump_callback_.is_null()) {
1785 stop_rtp_dump_callback_ =
1786 base::Bind(&P2PSocketDispatcherHost::StopRtpDumpOnUIThread,
1787 p2p_socket_dispatcher_host_);
1789 return stop_rtp_dump_callback_;
1791 #endif
1793 IPC::ChannelProxy* RenderProcessHostImpl::GetChannel() {
1794 return channel_.get();
1797 void RenderProcessHostImpl::AddFilter(BrowserMessageFilter* filter) {
1798 channel_->AddFilter(filter->GetFilter());
1801 bool RenderProcessHostImpl::FastShutdownForPageCount(size_t count) {
1802 if (static_cast<size_t>(GetActiveViewCount()) == count)
1803 return FastShutdownIfPossible();
1804 return false;
1807 bool RenderProcessHostImpl::FastShutdownStarted() const {
1808 return fast_shutdown_started_;
1811 // static
1812 void RenderProcessHostImpl::RegisterHost(int host_id, RenderProcessHost* host) {
1813 g_all_hosts.Get().AddWithID(host, host_id);
1816 // static
1817 void RenderProcessHostImpl::UnregisterHost(int host_id) {
1818 RenderProcessHost* host = g_all_hosts.Get().Lookup(host_id);
1819 if (!host)
1820 return;
1822 g_all_hosts.Get().Remove(host_id);
1824 // Look up the map of site to process for the given browser_context,
1825 // in case we need to remove this process from it. It will be registered
1826 // under any sites it rendered that use process-per-site mode.
1827 SiteProcessMap* map =
1828 GetSiteProcessMapForBrowserContext(host->GetBrowserContext());
1829 map->RemoveProcess(host);
1832 // static
1833 void RenderProcessHostImpl::FilterURL(RenderProcessHost* rph,
1834 bool empty_allowed,
1835 GURL* url) {
1836 ChildProcessSecurityPolicyImpl* policy =
1837 ChildProcessSecurityPolicyImpl::GetInstance();
1839 if (empty_allowed && url->is_empty())
1840 return;
1842 // The browser process should never hear the swappedout:// URL from any
1843 // of the renderer's messages. Check for this in debug builds, but don't
1844 // let it crash a release browser.
1845 DCHECK(GURL(kSwappedOutURL) != *url);
1847 if (!url->is_valid()) {
1848 // Have to use about:blank for the denied case, instead of an empty GURL.
1849 // This is because the browser treats navigation to an empty GURL as a
1850 // navigation to the home page. This is often a privileged page
1851 // (chrome://newtab/) which is exactly what we don't want.
1852 *url = GURL(url::kAboutBlankURL);
1853 return;
1856 if (url->SchemeIs(url::kAboutScheme)) {
1857 // The renderer treats all URLs in the about: scheme as being about:blank.
1858 // Canonicalize about: URLs to about:blank.
1859 *url = GURL(url::kAboutBlankURL);
1862 // Do not allow browser plugin guests to navigate to non-web URLs, since they
1863 // cannot swap processes or grant bindings.
1864 bool non_web_url_in_guest = rph->IsForGuestsOnly() &&
1865 !(url->is_valid() && policy->IsWebSafeScheme(url->scheme()));
1867 if (non_web_url_in_guest || !policy->CanRequestURL(rph->GetID(), *url)) {
1868 // If this renderer is not permitted to request this URL, we invalidate the
1869 // URL. This prevents us from storing the blocked URL and becoming confused
1870 // later.
1871 VLOG(1) << "Blocked URL " << url->spec();
1872 *url = GURL(url::kAboutBlankURL);
1876 // static
1877 bool RenderProcessHostImpl::IsSuitableHost(
1878 RenderProcessHost* host,
1879 BrowserContext* browser_context,
1880 const GURL& site_url) {
1881 if (run_renderer_in_process())
1882 return true;
1884 if (host->GetBrowserContext() != browser_context)
1885 return false;
1887 // Do not allow sharing of guest hosts. This is to prevent bugs where guest
1888 // and non-guest storage gets mixed. In the future, we might consider enabling
1889 // the sharing of guests, in this case this check should be removed and
1890 // InSameStoragePartition should handle the possible sharing.
1891 if (host->IsForGuestsOnly())
1892 return false;
1894 // Check whether the given host and the intended site_url will be using the
1895 // same StoragePartition, since a RenderProcessHost can only support a single
1896 // StoragePartition. This is relevant for packaged apps.
1897 StoragePartition* dest_partition =
1898 BrowserContext::GetStoragePartitionForSite(browser_context, site_url);
1899 if (!host->InSameStoragePartition(dest_partition))
1900 return false;
1902 // TODO(nick): Consult the SiteIsolationPolicy here. https://crbug.com/513036
1903 if (ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
1904 host->GetID()) !=
1905 WebUIControllerFactoryRegistry::GetInstance()->UseWebUIBindingsForURL(
1906 browser_context, site_url)) {
1907 return false;
1910 return GetContentClient()->browser()->IsSuitableHost(host, site_url);
1913 // static
1914 bool RenderProcessHost::run_renderer_in_process() {
1915 return g_run_renderer_in_process_;
1918 // static
1919 void RenderProcessHost::SetRunRendererInProcess(bool value) {
1920 g_run_renderer_in_process_ = value;
1922 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
1923 if (value) {
1924 if (!command_line->HasSwitch(switches::kLang)) {
1925 // Modify the current process' command line to include the browser locale,
1926 // as the renderer expects this flag to be set.
1927 const std::string locale =
1928 GetContentClient()->browser()->GetApplicationLocale();
1929 command_line->AppendSwitchASCII(switches::kLang, locale);
1931 // TODO(piman): we should really send configuration through bools rather
1932 // than by parsing strings, i.e. sending an IPC rather than command line
1933 // args. crbug.com/314909
1934 AppendCompositorCommandLineFlags(command_line);
1938 // static
1939 RenderProcessHost::iterator RenderProcessHost::AllHostsIterator() {
1940 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1941 return iterator(g_all_hosts.Pointer());
1944 // static
1945 RenderProcessHost* RenderProcessHost::FromID(int render_process_id) {
1946 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1947 return g_all_hosts.Get().Lookup(render_process_id);
1950 // static
1951 bool RenderProcessHost::ShouldTryToUseExistingProcessHost(
1952 BrowserContext* browser_context, const GURL& url) {
1953 // If --site-per-process is enabled, do not try to reuse renderer processes
1954 // when over the limit.
1955 // TODO(nick): This is overly conservative and isn't launchable. Move this
1956 // logic into IsSuitableHost, and check |url| against the URL the process is
1957 // dedicated to. This will allow pages from the same site to share, and will
1958 // also allow non-isolated sites to share processes. https://crbug.com/513036
1959 if (SiteIsolationPolicy::AreCrossProcessFramesPossible())
1960 return false;
1962 if (run_renderer_in_process())
1963 return true;
1965 // NOTE: Sometimes it's necessary to create more render processes than
1966 // GetMaxRendererProcessCount(), for instance when we want to create
1967 // a renderer process for a browser context that has no existing
1968 // renderers. This is OK in moderation, since the
1969 // GetMaxRendererProcessCount() is conservative.
1970 if (g_all_hosts.Get().size() >= GetMaxRendererProcessCount())
1971 return true;
1973 return GetContentClient()->browser()->
1974 ShouldTryToUseExistingProcessHost(browser_context, url);
1977 // static
1978 RenderProcessHost* RenderProcessHost::GetExistingProcessHost(
1979 BrowserContext* browser_context,
1980 const GURL& site_url) {
1981 // First figure out which existing renderers we can use.
1982 std::vector<RenderProcessHost*> suitable_renderers;
1983 suitable_renderers.reserve(g_all_hosts.Get().size());
1985 iterator iter(AllHostsIterator());
1986 while (!iter.IsAtEnd()) {
1987 if (GetContentClient()->browser()->MayReuseHost(iter.GetCurrentValue()) &&
1988 RenderProcessHostImpl::IsSuitableHost(
1989 iter.GetCurrentValue(),
1990 browser_context, site_url)) {
1991 suitable_renderers.push_back(iter.GetCurrentValue());
1993 iter.Advance();
1996 // Now pick a random suitable renderer, if we have any.
1997 if (!suitable_renderers.empty()) {
1998 int suitable_count = static_cast<int>(suitable_renderers.size());
1999 int random_index = base::RandInt(0, suitable_count - 1);
2000 return suitable_renderers[random_index];
2003 return NULL;
2006 // static
2007 bool RenderProcessHost::ShouldUseProcessPerSite(
2008 BrowserContext* browser_context,
2009 const GURL& url) {
2010 // Returns true if we should use the process-per-site model. This will be
2011 // the case if the --process-per-site switch is specified, or in
2012 // process-per-site-instance for particular sites (e.g., WebUI).
2013 // Note that --single-process is handled in ShouldTryToUseExistingProcessHost.
2014 const base::CommandLine& command_line =
2015 *base::CommandLine::ForCurrentProcess();
2016 if (command_line.HasSwitch(switches::kProcessPerSite))
2017 return true;
2019 // We want to consolidate particular sites like WebUI even when we are using
2020 // the process-per-tab or process-per-site-instance models.
2021 // Note: DevTools pages have WebUI type but should not reuse the same host.
2022 if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL(
2023 browser_context, url) &&
2024 !url.SchemeIs(kChromeDevToolsScheme)) {
2025 return true;
2028 // Otherwise let the content client decide, defaulting to false.
2029 return GetContentClient()->browser()->ShouldUseProcessPerSite(browser_context,
2030 url);
2033 // static
2034 RenderProcessHost* RenderProcessHostImpl::GetProcessHostForSite(
2035 BrowserContext* browser_context,
2036 const GURL& url) {
2037 // Look up the map of site to process for the given browser_context.
2038 SiteProcessMap* map =
2039 GetSiteProcessMapForBrowserContext(browser_context);
2041 // See if we have an existing process with appropriate bindings for this site.
2042 // If not, the caller should create a new process and register it.
2043 std::string site = SiteInstance::GetSiteForURL(browser_context, url)
2044 .possibly_invalid_spec();
2045 RenderProcessHost* host = map->FindProcess(site);
2046 if (host && (!GetContentClient()->browser()->MayReuseHost(host) ||
2047 !IsSuitableHost(host, browser_context, url))) {
2048 // The registered process does not have an appropriate set of bindings for
2049 // the url. Remove it from the map so we can register a better one.
2050 RecordAction(
2051 base::UserMetricsAction("BindingsMismatch_GetProcessHostPerSite"));
2052 map->RemoveProcess(host);
2053 host = NULL;
2056 return host;
2059 void RenderProcessHostImpl::RegisterProcessHostForSite(
2060 BrowserContext* browser_context,
2061 RenderProcessHost* process,
2062 const GURL& url) {
2063 // Look up the map of site to process for the given browser_context.
2064 SiteProcessMap* map =
2065 GetSiteProcessMapForBrowserContext(browser_context);
2067 // Only register valid, non-empty sites. Empty or invalid sites will not
2068 // use process-per-site mode. We cannot check whether the process has
2069 // appropriate bindings here, because the bindings have not yet been granted.
2070 std::string site = SiteInstance::GetSiteForURL(browser_context, url)
2071 .possibly_invalid_spec();
2072 if (!site.empty())
2073 map->RegisterProcess(site, process);
2076 void RenderProcessHostImpl::ProcessDied(bool already_dead,
2077 RendererClosedDetails* known_details) {
2078 // Our child process has died. If we didn't expect it, it's a crash.
2079 // In any case, we need to let everyone know it's gone.
2080 // The OnChannelError notification can fire multiple times due to nested sync
2081 // calls to a renderer. If we don't have a valid channel here it means we
2082 // already handled the error.
2084 // It should not be possible for us to be called re-entrantly.
2085 DCHECK(!within_process_died_observer_);
2087 // It should not be possible for a process death notification to come in while
2088 // we are dying.
2089 DCHECK(!deleting_soon_);
2091 // child_process_launcher_ can be NULL in single process mode or if fast
2092 // termination happened.
2093 base::TerminationStatus status = base::TERMINATION_STATUS_NORMAL_TERMINATION;
2094 int exit_code = 0;
2095 if (known_details) {
2096 status = known_details->status;
2097 exit_code = known_details->exit_code;
2098 } else if (child_process_launcher_.get()) {
2099 status = child_process_launcher_->GetChildTerminationStatus(already_dead,
2100 &exit_code);
2101 if (already_dead && status == base::TERMINATION_STATUS_STILL_RUNNING) {
2102 // May be in case of IPC error, if it takes long time for renderer
2103 // to exit. Child process will be killed in any case during
2104 // child_process_launcher_.reset(). Make sure we will not broadcast
2105 // FrameHostMsg_RenderProcessGone with status
2106 // TERMINATION_STATUS_STILL_RUNNING, since this will break WebContentsImpl
2107 // logic.
2108 status = base::TERMINATION_STATUS_PROCESS_CRASHED;
2112 RendererClosedDetails details(status, exit_code);
2113 mojo_application_host_->WillDestroySoon();
2115 child_process_launcher_.reset();
2116 channel_.reset();
2117 while (!queued_messages_.empty()) {
2118 delete queued_messages_.front();
2119 queued_messages_.pop();
2122 within_process_died_observer_ = true;
2123 NotificationService::current()->Notify(
2124 NOTIFICATION_RENDERER_PROCESS_CLOSED,
2125 Source<RenderProcessHost>(this),
2126 Details<RendererClosedDetails>(&details));
2127 FOR_EACH_OBSERVER(RenderProcessHostObserver,
2128 observers_,
2129 RenderProcessExited(this, status, exit_code));
2130 within_process_died_observer_ = false;
2132 gpu_message_filter_ = NULL;
2133 message_port_message_filter_ = NULL;
2134 RemoveUserData(kSessionStorageHolderKey);
2136 IDMap<IPC::Listener>::iterator iter(&listeners_);
2137 while (!iter.IsAtEnd()) {
2138 iter.GetCurrentValue()->OnMessageReceived(
2139 FrameHostMsg_RenderProcessGone(iter.GetCurrentKey(),
2140 static_cast<int>(status),
2141 exit_code));
2142 iter.Advance();
2145 mojo_application_host_.reset(new MojoApplicationHost);
2147 // It's possible that one of the calls out to the observers might have caused
2148 // this object to be no longer needed.
2149 if (delayed_cleanup_needed_)
2150 Cleanup();
2152 // This object is not deleted at this point and might be reused later.
2153 // TODO(darin): clean this up
2156 int RenderProcessHost::GetActiveViewCount() {
2157 int num_active_views = 0;
2158 scoped_ptr<RenderWidgetHostIterator> widgets(
2159 RenderWidgetHost::GetRenderWidgetHosts());
2160 while (RenderWidgetHost* widget = widgets->GetNextHost()) {
2161 // Count only RenderWidgetHosts in this process.
2162 if (widget->GetProcess()->GetID() == GetID())
2163 num_active_views++;
2165 return num_active_views;
2168 // Frame subscription API for this class is for accelerated composited path
2169 // only. These calls are redirected to GpuMessageFilter.
2170 void RenderProcessHostImpl::BeginFrameSubscription(
2171 int route_id,
2172 scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) {
2173 if (!gpu_message_filter_)
2174 return;
2175 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
2176 &GpuMessageFilter::BeginFrameSubscription,
2177 gpu_message_filter_,
2178 route_id, base::Passed(&subscriber)));
2181 void RenderProcessHostImpl::EndFrameSubscription(int route_id) {
2182 if (!gpu_message_filter_)
2183 return;
2184 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
2185 &GpuMessageFilter::EndFrameSubscription,
2186 gpu_message_filter_,
2187 route_id));
2190 #if defined(ENABLE_WEBRTC)
2191 void RenderProcessHostImpl::WebRtcLogMessage(const std::string& message) {
2192 DCHECK_CURRENTLY_ON(BrowserThread::UI);
2193 if (!webrtc_log_message_callback_.is_null())
2194 webrtc_log_message_callback_.Run(message);
2196 #endif
2198 void RenderProcessHostImpl::ReleaseOnCloseACK(
2199 RenderProcessHost* host,
2200 const SessionStorageNamespaceMap& sessions,
2201 int view_route_id) {
2202 DCHECK(host);
2203 if (sessions.empty())
2204 return;
2205 SessionStorageHolder* holder = static_cast<SessionStorageHolder*>
2206 (host->GetUserData(kSessionStorageHolderKey));
2207 if (!holder) {
2208 holder = new SessionStorageHolder();
2209 host->SetUserData(
2210 kSessionStorageHolderKey,
2211 holder);
2213 holder->Hold(sessions, view_route_id);
2216 void RenderProcessHostImpl::OnShutdownRequest() {
2217 // Don't shut down if there are active RenderViews, or if there are pending
2218 // RenderViews being swapped back in.
2219 // In single process mode, we never shutdown the renderer.
2220 int num_active_views = GetActiveViewCount();
2221 if (pending_views_ || num_active_views > 0 || run_renderer_in_process())
2222 return;
2224 // Notify any contents that might have swapped out renderers from this
2225 // process. They should not attempt to swap them back in.
2226 FOR_EACH_OBSERVER(RenderProcessHostObserver, observers_,
2227 RenderProcessWillExit(this));
2229 mojo_application_host_->WillDestroySoon();
2231 Send(new ChildProcessMsg_Shutdown());
2234 void RenderProcessHostImpl::SuddenTerminationChanged(bool enabled) {
2235 SetSuddenTerminationAllowed(enabled);
2238 void RenderProcessHostImpl::SetBackgrounded(bool backgrounded) {
2239 TRACE_EVENT1("renderer_host", "RenderProcessHostImpl::SetBackgrounded",
2240 "backgrounded", backgrounded);
2241 // Note: we always set the backgrounded_ value. If the process is NULL
2242 // (and hence hasn't been created yet), we will set the process priority
2243 // later when we create the process.
2244 backgrounded_ = backgrounded;
2245 if (!child_process_launcher_.get() || child_process_launcher_->IsStarting())
2246 return;
2248 // Don't background processes which have active audio streams.
2249 if (backgrounded_ && audio_renderer_host_->HasActiveAudio())
2250 return;
2252 const base::CommandLine* command_line =
2253 base::CommandLine::ForCurrentProcess();
2254 if (command_line->HasSwitch(switches::kDisableRendererBackgrounding))
2255 return;
2257 #if defined(OS_WIN)
2258 // The cbstext.dll loads as a global GetMessage hook in the browser process
2259 // and intercepts/unintercepts the kernel32 API SetPriorityClass in a
2260 // background thread. If the UI thread invokes this API just when it is
2261 // intercepted the stack is messed up on return from the interceptor
2262 // which causes random crashes in the browser process. Our hack for now
2263 // is to not invoke the SetPriorityClass API if the dll is loaded.
2264 if (GetModuleHandle(L"cbstext.dll"))
2265 return;
2266 #endif // OS_WIN
2268 #if defined(OS_WIN) || defined(OS_MACOSX)
2269 // Same as below, but bound to an experiment (http://crbug.com/458594 on
2270 // Windows, http://crbug.com/398103 on the Mac). Enabled by default in the
2271 // absence of field trials to get coverage on the perf waterfall.
2272 base::FieldTrial* trial =
2273 base::FieldTrialList::Find("BackgroundRendererProcesses");
2274 if (!trial || !base::StartsWith(trial->group_name(), "Disallow",
2275 base::CompareCase::SENSITIVE)) {
2276 child_process_launcher_->SetProcessBackgrounded(backgrounded);
2278 #else
2279 // Control the background state from the browser process, otherwise the task
2280 // telling the renderer to "unbackground" itself may be preempted by other
2281 // tasks executing at lowered priority ahead of it or simply by not being
2282 // swiftly scheduled by the OS per the low process priority
2283 // (http://crbug.com/398103).
2284 child_process_launcher_->SetProcessBackgrounded(backgrounded);
2285 #endif // OS_WIN
2287 // Notify the child process of background state.
2288 Send(new ChildProcessMsg_SetProcessBackgrounded(backgrounded));
2291 void RenderProcessHostImpl::OnProcessLaunched() {
2292 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841
2293 // is fixed.
2294 tracked_objects::ScopedTracker tracking_profile1(
2295 FROM_HERE_WITH_EXPLICIT_FUNCTION(
2296 "465841 RenderProcessHostImpl::OnProcessLaunched::Start"));
2297 // No point doing anything, since this object will be destructed soon. We
2298 // especially don't want to send the RENDERER_PROCESS_CREATED notification,
2299 // since some clients might expect a RENDERER_PROCESS_TERMINATED afterwards to
2300 // properly cleanup.
2301 if (deleting_soon_)
2302 return;
2304 if (child_process_launcher_) {
2305 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841
2306 // is fixed.
2307 tracked_objects::ScopedTracker tracking_profile2(
2308 FROM_HERE_WITH_EXPLICIT_FUNCTION(
2309 "465841 RenderProcessHostImpl::OnProcessLaunched::Backgrounded"));
2310 DCHECK(child_process_launcher_->GetProcess().IsValid());
2311 SetBackgrounded(backgrounded_);
2314 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841
2315 // is fixed.
2316 tracked_objects::ScopedTracker tracking_profile3(
2317 FROM_HERE_WITH_EXPLICIT_FUNCTION(
2318 "465841 RenderProcessHostImpl::OnProcessLaunched::Notify"));
2319 // NOTE: This needs to be before sending queued messages because
2320 // ExtensionService uses this notification to initialize the renderer process
2321 // with state that must be there before any JavaScript executes.
2323 // The queued messages contain such things as "navigate". If this notification
2324 // was after, we can end up executing JavaScript before the initialization
2325 // happens.
2326 NotificationService::current()->Notify(
2327 NOTIFICATION_RENDERER_PROCESS_CREATED,
2328 Source<RenderProcessHost>(this),
2329 NotificationService::NoDetails());
2331 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841
2332 // is fixed.
2333 tracked_objects::ScopedTracker tracking_profile4(
2334 FROM_HERE_WITH_EXPLICIT_FUNCTION(
2335 "465841 RenderProcessHostImpl::OnProcessLaunched::MojoActivate"));
2336 // Allow Mojo to be setup before the renderer sees any Chrome IPC messages.
2337 // This way, Mojo can be safely used from the renderer in response to any
2338 // Chrome IPC message.
2339 mojo_application_host_->Activate(this, GetHandle());
2341 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841
2342 // is fixed.
2343 tracked_objects::ScopedTracker tracking_profile5(
2344 FROM_HERE_WITH_EXPLICIT_FUNCTION(
2345 "465841 RenderProcessHostImpl::OnProcessLaunched::MojoClientLaunch"));
2347 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841
2348 // is fixed.
2349 tracked_objects::ScopedTracker tracking_profile6(
2350 FROM_HERE_WITH_EXPLICIT_FUNCTION(
2351 "465841 "
2352 "RenderProcessHostImpl::OnProcessLaunched::SendQueuedMessages"));
2353 while (!queued_messages_.empty()) {
2354 Send(queued_messages_.front());
2355 queued_messages_.pop();
2358 #if defined(ENABLE_WEBRTC)
2359 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841
2360 // is fixed.
2361 tracked_objects::ScopedTracker tracking_profile7(
2362 FROM_HERE_WITH_EXPLICIT_FUNCTION(
2363 "465841 RenderProcessHostImpl::OnProcessLaunched::EnableAec"));
2364 if (WebRTCInternals::GetInstance()->aec_dump_enabled())
2365 EnableAecDump(WebRTCInternals::GetInstance()->aec_dump_file_path());
2366 #endif
2369 void RenderProcessHostImpl::OnProcessLaunchFailed() {
2370 // If this object will be destructed soon, then observers have already been
2371 // sent a RenderProcessHostDestroyed notification, and we must observe our
2372 // contract that says that will be the last call.
2373 if (deleting_soon_)
2374 return;
2376 RendererClosedDetails details { base::TERMINATION_STATUS_PROCESS_WAS_KILLED,
2377 -1 };
2378 ProcessDied(true, &details);
2381 scoped_refptr<AudioRendererHost>
2382 RenderProcessHostImpl::audio_renderer_host() const {
2383 return audio_renderer_host_;
2386 void RenderProcessHostImpl::OnUserMetricsRecordAction(
2387 const std::string& action) {
2388 RecordComputedAction(action);
2391 void RenderProcessHostImpl::OnCloseACK(int old_route_id) {
2392 SessionStorageHolder* holder = static_cast<SessionStorageHolder*>
2393 (GetUserData(kSessionStorageHolderKey));
2394 if (!holder)
2395 return;
2396 holder->Release(old_route_id);
2399 void RenderProcessHostImpl::OnSavedPageAsMHTML(int job_id, int64 data_size) {
2400 MHTMLGenerationManager::GetInstance()->MHTMLGenerated(job_id, data_size);
2403 void RenderProcessHostImpl::OnGpuSwitched() {
2404 // We are updating all widgets including swapped out ones.
2405 scoped_ptr<RenderWidgetHostIterator> widgets(
2406 RenderWidgetHostImpl::GetAllRenderWidgetHosts());
2407 while (RenderWidgetHost* widget = widgets->GetNextHost()) {
2408 if (!widget->IsRenderView())
2409 continue;
2411 // Skip widgets in other processes.
2412 if (widget->GetProcess()->GetID() != GetID())
2413 continue;
2415 RenderViewHost* rvh = RenderViewHost::From(widget);
2416 rvh->OnWebkitPreferencesChanged();
2420 #if defined(ENABLE_WEBRTC)
2421 void RenderProcessHostImpl::OnRegisterAecDumpConsumer(int id) {
2422 BrowserThread::PostTask(
2423 BrowserThread::UI,
2424 FROM_HERE,
2425 base::Bind(
2426 &RenderProcessHostImpl::RegisterAecDumpConsumerOnUIThread,
2427 weak_factory_.GetWeakPtr(),
2428 id));
2431 void RenderProcessHostImpl::OnUnregisterAecDumpConsumer(int id) {
2432 BrowserThread::PostTask(
2433 BrowserThread::UI,
2434 FROM_HERE,
2435 base::Bind(
2436 &RenderProcessHostImpl::UnregisterAecDumpConsumerOnUIThread,
2437 weak_factory_.GetWeakPtr(),
2438 id));
2441 void RenderProcessHostImpl::RegisterAecDumpConsumerOnUIThread(int id) {
2442 DCHECK_CURRENTLY_ON(BrowserThread::UI);
2443 aec_dump_consumers_.push_back(id);
2444 if (WebRTCInternals::GetInstance()->aec_dump_enabled()) {
2445 EnableAecDumpForId(WebRTCInternals::GetInstance()->aec_dump_file_path(),
2446 id);
2450 void RenderProcessHostImpl::UnregisterAecDumpConsumerOnUIThread(int id) {
2451 DCHECK_CURRENTLY_ON(BrowserThread::UI);
2452 for (std::vector<int>::iterator it = aec_dump_consumers_.begin();
2453 it != aec_dump_consumers_.end(); ++it) {
2454 if (*it == id) {
2455 aec_dump_consumers_.erase(it);
2456 break;
2461 #if defined(OS_WIN)
2462 #define IntToStringType base::IntToString16
2463 #else
2464 #define IntToStringType base::IntToString
2465 #endif
2467 void RenderProcessHostImpl::EnableAecDumpForId(const base::FilePath& file,
2468 int id) {
2469 DCHECK_CURRENTLY_ON(BrowserThread::UI);
2470 base::FilePath unique_file =
2471 file.AddExtension(IntToStringType(base::GetProcId(GetHandle())))
2472 .AddExtension(IntToStringType(id));
2473 BrowserThread::PostTaskAndReplyWithResult(
2474 BrowserThread::FILE, FROM_HERE,
2475 base::Bind(&CreateAecDumpFileForProcess, unique_file, GetHandle()),
2476 base::Bind(&RenderProcessHostImpl::SendAecDumpFileToRenderer,
2477 weak_factory_.GetWeakPtr(),
2478 id));
2481 #undef IntToStringType
2483 void RenderProcessHostImpl::SendAecDumpFileToRenderer(
2484 int id,
2485 IPC::PlatformFileForTransit file_for_transit) {
2486 if (file_for_transit == IPC::InvalidPlatformFileForTransit())
2487 return;
2488 Send(new AecDumpMsg_EnableAecDump(id, file_for_transit));
2491 void RenderProcessHostImpl::SendDisableAecDumpToRenderer() {
2492 Send(new AecDumpMsg_DisableAecDump());
2494 #endif
2496 void RenderProcessHostImpl::IncrementWorkerRefCount() {
2497 DCHECK_CURRENTLY_ON(BrowserThread::UI);
2498 ++worker_ref_count_;
2499 if (worker_ref_count_ > max_worker_count_)
2500 max_worker_count_ = worker_ref_count_;
2503 void RenderProcessHostImpl::DecrementWorkerRefCount() {
2504 DCHECK_CURRENTLY_ON(BrowserThread::UI);
2505 DCHECK_GT(worker_ref_count_, 0);
2506 --worker_ref_count_;
2507 if (worker_ref_count_ == 0)
2508 Cleanup();
2511 void RenderProcessHostImpl::GetAudioOutputControllers(
2512 const GetAudioOutputControllersCallback& callback) const {
2513 audio_renderer_host()->GetOutputControllers(callback);
2516 BluetoothDispatcherHost* RenderProcessHostImpl::GetBluetoothDispatcherHost() {
2517 return bluetooth_dispatcher_host_.get();
2520 } // namespace content