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