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