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