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