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