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