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