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