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