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