summaryrefslogtreecommitdiffstats
path: root/chromium/content/browser/renderer_host/render_process_host_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/browser/renderer_host/render_process_host_impl.cc')
-rw-r--r--chromium/content/browser/renderer_host/render_process_host_impl.cc1149
1 files changed, 803 insertions, 346 deletions
diff --git a/chromium/content/browser/renderer_host/render_process_host_impl.cc b/chromium/content/browser/renderer_host/render_process_host_impl.cc
index 5d975e9119d..2eafd8c9c47 100644
--- a/chromium/content/browser/renderer_host/render_process_host_impl.cc
+++ b/chromium/content/browser/renderer_host/render_process_host_impl.cc
@@ -21,14 +21,16 @@
#include "base/callback.h"
#include "base/command_line.h"
#include "base/debug/trace_event.h"
+#include "base/files/file.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
+#include "base/numerics/safe_math.h"
#include "base/path_service.h"
-#include "base/platform_file.h"
#include "base/rand_util.h"
#include "base/stl_util.h"
+#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/supports_user_data.h"
#include "base/sys_info.h"
@@ -38,13 +40,14 @@
#include "cc/base/switches.h"
#include "content/browser/appcache/appcache_dispatcher_host.h"
#include "content/browser/appcache/chrome_appcache_service.h"
+#include "content/browser/battery_status/battery_status_message_filter.h"
+#include "content/browser/browser_child_process_host_impl.h"
#include "content/browser/browser_main.h"
#include "content/browser/browser_main_loop.h"
-#include "content/browser/browser_plugin/browser_plugin_geolocation_permission_context.h"
#include "content/browser/browser_plugin/browser_plugin_message_filter.h"
#include "content/browser/child_process_security_policy_impl.h"
-#include "content/browser/device_orientation/device_motion_message_filter.h"
-#include "content/browser/device_orientation/device_orientation_message_filter.h"
+#include "content/browser/device_sensors/device_motion_message_filter.h"
+#include "content/browser/device_sensors/device_orientation_message_filter.h"
#include "content/browser/dom_storage/dom_storage_context_wrapper.h"
#include "content/browser/dom_storage/dom_storage_message_filter.h"
#include "content/browser/download/mhtml_generation_manager.h"
@@ -60,12 +63,15 @@
#include "content/browser/indexed_db/indexed_db_dispatcher_host.h"
#include "content/browser/loader/resource_message_filter.h"
#include "content/browser/loader/resource_scheduler_filter.h"
-#include "content/browser/media/android/browser_demuxer_android.h"
+#include "content/browser/media/capture/audio_mirroring_manager.h"
#include "content/browser/media/media_internals.h"
+#include "content/browser/media/midi_host.h"
#include "content/browser/message_port_message_filter.h"
#include "content/browser/mime_registry_message_filter.h"
+#include "content/browser/mojo/mojo_application_host.h"
#include "content/browser/plugin_service_impl.h"
#include "content/browser/profiler_message_filter.h"
+#include "content/browser/push_messaging_message_filter.h"
#include "content/browser/quota_dispatcher_host.h"
#include "content/browser/renderer_host/clipboard_message_filter.h"
#include "content/browser/renderer_host/database_message_filter.h"
@@ -73,12 +79,9 @@
#include "content/browser/renderer_host/gamepad_browser_message_filter.h"
#include "content/browser/renderer_host/gpu_message_filter.h"
#include "content/browser/renderer_host/media/audio_input_renderer_host.h"
-#include "content/browser/renderer_host/media/audio_mirroring_manager.h"
#include "content/browser/renderer_host/media/audio_renderer_host.h"
#include "content/browser/renderer_host/media/device_request_message_filter.h"
#include "content/browser/renderer_host/media/media_stream_dispatcher_host.h"
-#include "content/browser/renderer_host/media/midi_dispatcher_host.h"
-#include "content/browser/renderer_host/media/midi_host.h"
#include "content/browser/renderer_host/media/peer_connection_tracker_host.h"
#include "content/browser/renderer_host/media/video_capture_host.h"
#include "content/browser/renderer_host/memory_benchmark_message_filter.h"
@@ -96,7 +99,7 @@
#include "content/browser/resolve_proxy_msg_helper.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/service_worker/service_worker_dispatcher_host.h"
-#include "content/browser/speech/input_tag_speech_dispatcher_host.h"
+#include "content/browser/shared_worker/shared_worker_message_filter.h"
#include "content/browser/speech/speech_recognition_dispatcher_host.h"
#include "content/browser/storage_partition_impl.h"
#include "content/browser/streams/stream_context.h"
@@ -107,10 +110,13 @@
#include "content/browser/worker_host/worker_storage_partition.h"
#include "content/common/child_process_host_impl.h"
#include "content/common/child_process_messages.h"
+#include "content/common/content_switches_internal.h"
+#include "content/common/gpu/client/gpu_memory_buffer_impl.h"
+#include "content/common/gpu/client/gpu_memory_buffer_impl_shm.h"
#include "content/common/gpu/gpu_messages.h"
+#include "content/common/mojo/mojo_messages.h"
#include "content/common/resource_messages.h"
#include "content/common/view_messages.h"
-#include "content/port/browser/render_widget_host_view_frame_subscriber.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/notification_service.h"
@@ -119,41 +125,63 @@
#include "content/public/browser/render_process_host_observer.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/render_widget_host_iterator.h"
+#include "content/public/browser/render_widget_host_view_frame_subscriber.h"
#include "content/public/browser/resource_context.h"
#include "content/public/browser/user_metrics.h"
+#include "content/public/browser/worker_service.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/process_type.h"
#include "content/public/common/result_codes.h"
+#include "content/public/common/sandboxed_process_launcher_delegate.h"
#include "content/public/common/url_constants.h"
#include "gpu/command_buffer/service/gpu_switches.h"
#include "ipc/ipc_channel.h"
#include "ipc/ipc_logging.h"
-#include "ipc/ipc_platform_file.h"
#include "ipc/ipc_switches.h"
#include "media/base/media_switches.h"
+#include "mojo/common/common_type_converters.h"
#include "net/url_request/url_request_context_getter.h"
#include "ppapi/shared_impl/ppapi_switches.h"
+#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/ui_base_switches.h"
#include "ui/events/event_switches.h"
#include "ui/gfx/switches.h"
#include "ui/gl/gl_switches.h"
+#include "ui/native_theme/native_theme_switches.h"
#include "webkit/browser/fileapi/sandbox_file_system_backend.h"
#include "webkit/common/resource_type.h"
+#if defined(OS_ANDROID)
+#include "content/browser/media/android/browser_demuxer_android.h"
+#include "content/browser/renderer_host/compositor_impl_android.h"
+#include "content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.h"
+#endif
+
+#if defined(OS_MACOSX)
+#include "content/common/gpu/client/gpu_memory_buffer_impl_io_surface.h"
+#endif
+
#if defined(OS_WIN)
+#include "base/strings/string_number_conversions.h"
#include "base/win/scoped_com_initializer.h"
#include "content/common/font_cache_dispatcher_win.h"
#include "content/common/sandbox_win.h"
-#include "content/public/common/sandboxed_process_launcher_delegate.h"
+#include "ui/gfx/win/dpi.h"
+#endif
+
+#if defined(OS_MACOSX)
+#include "content/public/common/sandbox_type_mac.h"
#endif
#if defined(ENABLE_WEBRTC)
+#include "content/browser/media/webrtc_internals.h"
+#include "content/browser/renderer_host/media/media_stream_track_metrics_host.h"
#include "content/browser/renderer_host/media/webrtc_identity_service_host.h"
+#include "content/common/media/aec_dump_messages.h"
+#include "content/common/media/media_stream_messages.h"
#endif
-#include "third_party/skia/include/core/SkBitmap.h"
-
extern bool g_exited_main_message_loop;
static const char* kSiteProcessMapKeyName = "content_site_process_map";
@@ -194,13 +222,33 @@ void GetContexts(
request.resource_type);
}
+#if defined(ENABLE_WEBRTC)
+// Creates a file used for diagnostic echo canceller recordings for handing
+// over to the renderer.
+IPC::PlatformFileForTransit CreateAecDumpFileForProcess(
+ base::FilePath file_path,
+ base::ProcessHandle process) {
+ DCHECK_CURRENTLY_ON(BrowserThread::FILE);
+ base::File dump_file(file_path,
+ base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_APPEND);
+ if (!dump_file.IsValid()) {
+ VLOG(1) << "Could not open AEC dump file, error=" <<
+ dump_file.error_details();
+ return IPC::InvalidPlatformFileForTransit();
+ }
+ return IPC::TakeFileHandleForProcess(dump_file.Pass(), process);
+}
+
+// Does nothing. Just to avoid races between enable and disable.
+void DisableAecDumpOnFileThread() {
+ DCHECK_CURRENTLY_ON(BrowserThread::FILE);
+}
+#endif
+
// the global list of all renderer processes
base::LazyInstance<IDMap<RenderProcessHost> >::Leaky
g_all_hosts = LAZY_INSTANCE_INITIALIZER;
-base::LazyInstance<scoped_refptr<BrowserPluginGeolocationPermissionContext> >
- g_browser_plugin_geolocation_context = LAZY_INSTANCE_INITIALIZER;
-
// Map of site to process, to ensure we only have one RenderProcessHost per
// site in process-per-site mode. Each map is specific to a BrowserContext.
class SiteProcessMap : public base::SupportsUserData::Data {
@@ -256,39 +304,89 @@ SiteProcessMap* GetSiteProcessMapForBrowserContext(BrowserContext* context) {
return map;
}
-#if defined(OS_WIN)
// NOTE: changes to this class need to be reviewed by the security team.
class RendererSandboxedProcessLauncherDelegate
: public content::SandboxedProcessLauncherDelegate {
public:
- RendererSandboxedProcessLauncherDelegate() {}
- virtual ~RendererSandboxedProcessLauncherDelegate() {}
+ RendererSandboxedProcessLauncherDelegate(IPC::ChannelProxy* channel)
+#if defined(OS_POSIX)
+ : ipc_fd_(channel->TakeClientFileDescriptor())
+#endif // OS_POSIX
+ {}
- virtual void ShouldSandbox(bool* in_sandbox) OVERRIDE {
-#if !defined (GOOGLE_CHROME_BUILD)
- if (CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kInProcessPlugins)) {
- *in_sandbox = false;
- }
-#endif
- }
+ virtual ~RendererSandboxedProcessLauncherDelegate() {}
+#if defined(OS_WIN)
virtual void PreSpawnTarget(sandbox::TargetPolicy* policy,
bool* success) {
AddBaseHandleClosePolicy(policy);
GetContentClient()->browser()->PreSpawnRenderer(policy, success);
}
-};
+
+#elif defined(OS_POSIX)
+ virtual bool ShouldUseZygote() OVERRIDE {
+ const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
+ CommandLine::StringType renderer_prefix =
+ browser_command_line.GetSwitchValueNative(switches::kRendererCmdPrefix);
+ return renderer_prefix.empty();
+ }
+ virtual int GetIpcFd() OVERRIDE {
+ return ipc_fd_;
+ }
+#if defined(OS_MACOSX)
+ virtual SandboxType GetSandboxType() OVERRIDE {
+ return SANDBOX_TYPE_RENDERER;
+ }
+#endif
#endif // OS_WIN
-} // namespace
+ private:
+#if defined(OS_POSIX)
+ int ipc_fd_;
+#endif // OS_POSIX
+};
-RendererMainThreadFactoryFunction g_renderer_main_thread_factory = NULL;
+#if defined(OS_MACOSX)
+void AddBooleanValue(CFMutableDictionaryRef dictionary,
+ const CFStringRef key,
+ bool value) {
+ CFDictionaryAddValue(
+ dictionary, key, value ? kCFBooleanTrue : kCFBooleanFalse);
+}
-void RenderProcessHost::RegisterRendererMainThreadFactory(
- RendererMainThreadFactoryFunction create) {
- g_renderer_main_thread_factory = create;
+void AddIntegerValue(CFMutableDictionaryRef dictionary,
+ const CFStringRef key,
+ int32 value) {
+ base::ScopedCFTypeRef<CFNumberRef> number(
+ CFNumberCreate(NULL, kCFNumberSInt32Type, &value));
+ CFDictionaryAddValue(dictionary, key, number.get());
}
+#endif
+
+const char kSessionStorageHolderKey[] = "kSessionStorageHolderKey";
+
+class SessionStorageHolder : public base::SupportsUserData::Data {
+ public:
+ SessionStorageHolder() {}
+ virtual ~SessionStorageHolder() {}
+
+ void Hold(const SessionStorageNamespaceMap& sessions, int view_route_id) {
+ session_storage_namespaces_awaiting_close_[view_route_id] = sessions;
+ }
+
+ void Release(int old_route_id) {
+ session_storage_namespaces_awaiting_close_.erase(old_route_id);
+ }
+
+ private:
+ std::map<int, SessionStorageNamespaceMap >
+ session_storage_namespaces_awaiting_close_;
+ DISALLOW_COPY_AND_ASSIGN(SessionStorageHolder);
+};
+
+} // namespace
+
+RendererMainThreadFactoryFunction g_renderer_main_thread_factory = NULL;
base::MessageLoop* g_in_process_thread;
@@ -351,30 +449,29 @@ void RenderProcessHost::SetMaxRendererProcessCount(size_t count) {
RenderProcessHostImpl::RenderProcessHostImpl(
BrowserContext* browser_context,
StoragePartitionImpl* storage_partition_impl,
- bool supports_browser_plugin,
- bool is_guest)
- : fast_shutdown_started_(false),
- deleting_soon_(false),
+ bool is_isolated_guest)
+ : fast_shutdown_started_(false),
+ deleting_soon_(false),
#ifndef NDEBUG
- is_self_deleted_(false),
+ is_self_deleted_(false),
#endif
- pending_views_(0),
- visible_widgets_(0),
- backgrounded_(true),
- cached_dibs_cleaner_(
- FROM_HERE, base::TimeDelta::FromSeconds(5),
- this, &RenderProcessHostImpl::ClearTransportDIBCache),
- is_initialized_(false),
- id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()),
- browser_context_(browser_context),
- storage_partition_impl_(storage_partition_impl),
- sudden_termination_allowed_(true),
- ignore_input_events_(false),
- supports_browser_plugin_(supports_browser_plugin),
- is_guest_(is_guest),
- gpu_observer_registered_(false),
- power_monitor_broadcaster_(this),
- geolocation_dispatcher_host_(NULL) {
+ pending_views_(0),
+ mojo_activation_required_(false),
+ visible_widgets_(0),
+ backgrounded_(true),
+ is_initialized_(false),
+ id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()),
+ browser_context_(browser_context),
+ storage_partition_impl_(storage_partition_impl),
+ sudden_termination_allowed_(true),
+ ignore_input_events_(false),
+ is_isolated_guest_(is_isolated_guest),
+ gpu_observer_registered_(false),
+ delayed_cleanup_needed_(false),
+ within_process_died_observer_(false),
+ power_monitor_broadcaster_(this),
+ worker_ref_count_(0),
+ weak_factory_(this) {
widget_helper_ = new RenderWidgetHelper();
ChildProcessSecurityPolicyImpl::GetInstance()->Add(GetID());
@@ -424,12 +521,21 @@ void RenderProcessHostImpl::ShutDownInProcessRenderer() {
}
}
+void RenderProcessHostImpl::RegisterRendererMainThreadFactory(
+ RendererMainThreadFactoryFunction create) {
+ g_renderer_main_thread_factory = create;
+}
+
RenderProcessHostImpl::~RenderProcessHostImpl() {
#ifndef NDEBUG
DCHECK(is_self_deleted_)
<< "RenderProcessHostImpl is destroyed by something other than itself";
#endif
+ // Make sure to clean up the in-process renderer before the channel, otherwise
+ // it may still run and have its IPCs fail, causing asserts.
+ in_process_renderer_.reset();
+
ChildProcessSecurityPolicyImpl::GetInstance()->Remove(GetID());
if (gpu_observer_registered_) {
@@ -444,7 +550,6 @@ RenderProcessHostImpl::~RenderProcessHostImpl() {
queued_messages_.pop();
}
- ClearTransportDIBCache();
UnregisterHost(GetID());
if (!CommandLine::ForCurrentProcess()->HasSwitch(
@@ -452,6 +557,10 @@ RenderProcessHostImpl::~RenderProcessHostImpl() {
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&RemoveShaderInfo, GetID()));
}
+
+#if defined(OS_ANDROID)
+ CompositorImpl::DestroyAllSurfaceTextures(GetID());
+#endif
}
void RenderProcessHostImpl::EnableSendQueue() {
@@ -489,15 +598,18 @@ bool RenderProcessHostImpl::Init() {
// Setup the IPC channel.
const std::string channel_id =
IPC::Channel::GenerateVerifiedChannelID(std::string());
- channel_.reset(
- new IPC::ChannelProxy(channel_id,
- IPC::Channel::MODE_SERVER,
- this,
- BrowserThread::GetMessageLoopProxyForThread(
- BrowserThread::IO).get()));
+ channel_ = IPC::ChannelProxy::Create(
+ channel_id,
+ IPC::Channel::MODE_SERVER,
+ this,
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get());
+
+ // Setup the Mojo channel.
+ mojo_application_host_.reset(new MojoApplicationHost());
+ mojo_application_host_->Init();
// Call the embedder first so that their IPC filters have priority.
- GetContentClient()->browser()->RenderProcessHostCreated(this);
+ GetContentClient()->browser()->RenderProcessWillLaunch(this);
CreateMessageFilters();
@@ -538,13 +650,7 @@ bool RenderProcessHostImpl::Init() {
// As long as there's no renderer prefix, we can use the zygote process
// at this stage.
child_process_launcher_.reset(new ChildProcessLauncher(
-#if defined(OS_WIN)
- new RendererSandboxedProcessLauncherDelegate,
-#elif defined(OS_POSIX)
- renderer_prefix.empty(),
- base::EnvironmentMap(),
- channel_->TakeClientFileDescriptor(),
-#endif
+ new RendererSandboxedProcessLauncherDelegate(channel_.get()),
cmd_line,
GetID(),
this));
@@ -561,24 +667,35 @@ bool RenderProcessHostImpl::Init() {
return true;
}
+void RenderProcessHostImpl::MaybeActivateMojo() {
+ // TODO(darin): Following security review, we can unconditionally initialize
+ // Mojo in all renderers. We will then be able to directly call Activate()
+ // from OnProcessLaunched.
+ if (!mojo_activation_required_)
+ return; // Waiting on someone to require Mojo.
+
+ if (!GetHandle())
+ return; // Waiting on renderer startup.
+
+ if (!mojo_application_host_->did_activate())
+ mojo_application_host_->Activate(this, GetHandle());
+}
+
void RenderProcessHostImpl::CreateMessageFilters() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
AddFilter(new ResourceSchedulerFilter(GetID()));
- MediaInternals* media_internals = MediaInternals::GetInstance();;
+ MediaInternals* media_internals = MediaInternals::GetInstance();
media::AudioManager* audio_manager =
BrowserMainLoop::GetInstance()->audio_manager();
// Add BrowserPluginMessageFilter to ensure it gets the first stab at messages
// from guests.
- if (supports_browser_plugin_) {
- scoped_refptr<BrowserPluginMessageFilter> bp_message_filter(
- new BrowserPluginMessageFilter(GetID(), IsGuest()));
- AddFilter(bp_message_filter.get());
- }
+ scoped_refptr<BrowserPluginMessageFilter> bp_message_filter(
+ new BrowserPluginMessageFilter(GetID()));
+ AddFilter(bp_message_filter.get());
scoped_refptr<RenderMessageFilter> render_message_filter(
new RenderMessageFilter(
GetID(),
- IsGuest(),
#if defined(ENABLE_PLUGINS)
PluginServiceImpl::GetInstance(),
#else
@@ -610,6 +727,7 @@ void RenderProcessHostImpl::CreateMessageFilters() {
storage_partition_impl_->GetAppCacheService(),
ChromeBlobStorageContext::GetFor(browser_context),
storage_partition_impl_->GetFileSystemContext(),
+ storage_partition_impl_->GetServiceWorkerContext(),
get_contexts_callback);
AddFilter(resource_message_filter);
@@ -630,8 +748,7 @@ void RenderProcessHostImpl::CreateMessageFilters() {
media_stream_manager);
AddFilter(audio_renderer_host_);
AddFilter(
- new MIDIHost(GetID(), BrowserMainLoop::GetInstance()->midi_manager()));
- AddFilter(new MIDIDispatcherHost(GetID(), browser_context));
+ new MidiHost(GetID(), BrowserMainLoop::GetInstance()->midi_manager()));
AddFilter(new VideoCaptureHost(media_stream_manager));
AddFilter(new AppCacheDispatcherHost(
storage_partition_impl_->GetAppCacheService(),
@@ -641,26 +758,11 @@ void RenderProcessHostImpl::CreateMessageFilters() {
GetID(),
storage_partition_impl_->GetDOMStorageContext()));
AddFilter(new IndexedDBDispatcherHost(
- storage_partition_impl_->GetIndexedDBContext()));
-
- scoped_refptr<ServiceWorkerDispatcherHost> service_worker_filter =
- new ServiceWorkerDispatcherHost(GetID());
- service_worker_filter->Init(
- storage_partition_impl_->GetServiceWorkerContext());
- AddFilter(service_worker_filter);
+ GetID(),
+ storage_partition_impl_->GetURLRequestContext(),
+ storage_partition_impl_->GetIndexedDBContext(),
+ ChromeBlobStorageContext::GetFor(browser_context)));
- if (IsGuest()) {
- if (!g_browser_plugin_geolocation_context.Get().get()) {
- g_browser_plugin_geolocation_context.Get() =
- new BrowserPluginGeolocationPermissionContext();
- }
- geolocation_dispatcher_host_ = GeolocationDispatcherHost::New(
- GetID(), g_browser_plugin_geolocation_context.Get().get());
- } else {
- geolocation_dispatcher_host_ = GeolocationDispatcherHost::New(
- GetID(), browser_context->GetGeolocationPermissionContext());
- }
- AddFilter(geolocation_dispatcher_host_);
gpu_message_filter_ = new GpuMessageFilter(GetID(), widget_helper_.get());
AddFilter(gpu_message_filter_);
#if defined(ENABLE_WEBRTC)
@@ -671,19 +773,17 @@ void RenderProcessHostImpl::CreateMessageFilters() {
AddFilter(new MediaStreamDispatcherHost(
GetID(),
browser_context->GetResourceContext()->GetMediaDeviceIDSalt(),
- media_stream_manager));
- AddFilter(
- new DeviceRequestMessageFilter(resource_context, media_stream_manager));
+ media_stream_manager,
+ resource_context));
+ AddFilter(new DeviceRequestMessageFilter(
+ resource_context, media_stream_manager, GetID()));
+ AddFilter(new MediaStreamTrackMetricsHost());
#endif
#if defined(ENABLE_PLUGINS)
AddFilter(new PepperRendererConnection(GetID()));
#endif
-#if defined(ENABLE_INPUT_SPEECH)
- AddFilter(new InputTagSpeechDispatcherHost(
- IsGuest(), GetID(), storage_partition_impl_->GetURLRequestContext()));
-#endif
AddFilter(new SpeechRecognitionDispatcherHost(
- IsGuest(), GetID(), storage_partition_impl_->GetURLRequestContext()));
+ GetID(), storage_partition_impl_->GetURLRequestContext()));
AddFilter(new FileAPIMessageFilter(
GetID(),
storage_partition_impl_->GetURLRequestContext(),
@@ -697,6 +797,10 @@ void RenderProcessHostImpl::CreateMessageFilters() {
#if defined(OS_MACOSX)
AddFilter(new TextInputClientMessageFilter(GetID()));
#elif defined(OS_WIN)
+ // The FontCacheDispatcher is required only when we're using GDI rendering.
+ // TODO(scottmg): pdf/ppapi still require the renderer to be able to precache
+ // GDI fonts (http://crbug.com/383227), even when using DirectWrite. This
+ // should eventually be if (!ShouldUseDirectWrite()) guarded.
channel_->AddFilter(new FontCacheDispatcher());
#elif defined(OS_ANDROID)
browser_demuxer_android_ = new BrowserDemuxerAndroid();
@@ -718,30 +822,57 @@ void RenderProcessHostImpl::CreateMessageFilters() {
base::Bind(&GetRequestContext, request_context,
media_request_context, ResourceType::SUB_RESOURCE));
- AddFilter(new WebSocketDispatcherHost(websocket_request_context_callback));
+ AddFilter(
+ new WebSocketDispatcherHost(GetID(), websocket_request_context_callback));
message_port_message_filter_ = new MessagePortMessageFilter(
base::Bind(&RenderWidgetHelper::GetNextRoutingID,
base::Unretained(widget_helper_.get())));
AddFilter(message_port_message_filter_);
- AddFilter(new WorkerMessageFilter(
- GetID(),
- resource_context,
- WorkerStoragePartition(
- storage_partition_impl_->GetURLRequestContext(),
- storage_partition_impl_->GetMediaURLRequestContext(),
- storage_partition_impl_->GetAppCacheService(),
- storage_partition_impl_->GetQuotaManager(),
- storage_partition_impl_->GetFileSystemContext(),
- storage_partition_impl_->GetDatabaseTracker(),
- storage_partition_impl_->GetIndexedDBContext()),
- message_port_message_filter_));
+ scoped_refptr<ServiceWorkerDispatcherHost> service_worker_filter =
+ new ServiceWorkerDispatcherHost(GetID(), message_port_message_filter_);
+ service_worker_filter->Init(
+ storage_partition_impl_->GetServiceWorkerContext());
+ AddFilter(service_worker_filter);
+
+ // If "--enable-embedded-shared-worker" is set, we use
+ // SharedWorkerMessageFilter in stead of WorkerMessageFilter.
+ if (WorkerService::EmbeddedSharedWorkerEnabled()) {
+ AddFilter(new SharedWorkerMessageFilter(
+ GetID(),
+ resource_context,
+ WorkerStoragePartition(
+ storage_partition_impl_->GetURLRequestContext(),
+ storage_partition_impl_->GetMediaURLRequestContext(),
+ storage_partition_impl_->GetAppCacheService(),
+ storage_partition_impl_->GetQuotaManager(),
+ storage_partition_impl_->GetFileSystemContext(),
+ storage_partition_impl_->GetDatabaseTracker(),
+ storage_partition_impl_->GetIndexedDBContext(),
+ storage_partition_impl_->GetServiceWorkerContext()),
+ message_port_message_filter_));
+ } else {
+ AddFilter(new WorkerMessageFilter(
+ GetID(),
+ resource_context,
+ WorkerStoragePartition(
+ storage_partition_impl_->GetURLRequestContext(),
+ storage_partition_impl_->GetMediaURLRequestContext(),
+ storage_partition_impl_->GetAppCacheService(),
+ storage_partition_impl_->GetQuotaManager(),
+ storage_partition_impl_->GetFileSystemContext(),
+ storage_partition_impl_->GetDatabaseTracker(),
+ storage_partition_impl_->GetIndexedDBContext(),
+ storage_partition_impl_->GetServiceWorkerContext()),
+ message_port_message_filter_));
+ }
#if defined(ENABLE_WEBRTC)
- AddFilter(new P2PSocketDispatcherHost(
+ p2p_socket_dispatcher_host_ = new P2PSocketDispatcherHost(
resource_context,
- browser_context->GetRequestContextForRenderProcess(GetID())));
+ browser_context->GetRequestContextForRenderProcess(GetID()));
+ AddFilter(p2p_socket_dispatcher_host_);
#endif
AddFilter(new TraceMessageFilter());
@@ -762,6 +893,8 @@ void RenderProcessHostImpl::CreateMessageFilters() {
AddFilter(new MemoryBenchmarkMessageFilter());
#endif
AddFilter(new VibrationMessageFilter());
+ AddFilter(new PushMessagingMessageFilter(GetID()));
+ AddFilter(new BatteryStatusMessageFilter());
}
int RenderProcessHostImpl::GetNextRoutingID() {
@@ -774,6 +907,10 @@ void RenderProcessHostImpl::ResumeDeferredNavigation(
widget_helper_->ResumeDeferredNavigation(request_id);
}
+void RenderProcessHostImpl::NotifyTimezoneChange() {
+ Send(new ViewMsg_TimezoneChange());
+}
+
void RenderProcessHostImpl::AddRoute(
int32 routing_id,
IPC::Listener* listener) {
@@ -865,14 +1002,39 @@ int RenderProcessHostImpl::VisibleWidgetCount() const {
return visible_widgets_;
}
-bool RenderProcessHostImpl::IsGuest() const {
- return is_guest_;
+bool RenderProcessHostImpl::IsIsolatedGuest() const {
+ return is_isolated_guest_;
}
StoragePartition* RenderProcessHostImpl::GetStoragePartition() const {
return storage_partition_impl_;
}
+static void AppendCompositorCommandLineFlags(CommandLine* command_line) {
+ if (IsPinchVirtualViewportEnabled())
+ command_line->AppendSwitch(cc::switches::kEnablePinchVirtualViewport);
+
+ if (IsThreadedCompositingEnabled())
+ command_line->AppendSwitch(switches::kEnableThreadedCompositing);
+
+ if (IsDelegatedRendererEnabled())
+ command_line->AppendSwitch(switches::kEnableDelegatedRenderer);
+
+ if (IsImplSidePaintingEnabled())
+ command_line->AppendSwitch(switches::kEnableImplSidePainting);
+
+ if (content::IsGpuRasterizationEnabled())
+ command_line->AppendSwitch(switches::kEnableGpuRasterization);
+
+ if (content::IsForceGpuRasterizationEnabled())
+ command_line->AppendSwitch(switches::kForceGpuRasterization);
+
+ // Appending disable-gpu-feature switches due to software rendering list.
+ GpuDataManagerImpl* gpu_data_manager = GpuDataManagerImpl::GetInstance();
+ DCHECK(gpu_data_manager);
+ gpu_data_manager->AppendRendererCommandLine(command_line);
+}
+
void RenderProcessHostImpl::AppendRendererCommandLine(
CommandLine* command_line) const {
// Pass the process type first, so it shows first in process listings.
@@ -898,22 +1060,18 @@ void RenderProcessHostImpl::AppendRendererCommandLine(
field_trial_states);
}
- if (content::IsThreadedCompositingEnabled())
- command_line->AppendSwitch(switches::kEnableThreadedCompositing);
-
- if (content::IsDelegatedRendererEnabled())
- command_line->AppendSwitch(switches::kEnableDelegatedRenderer);
-
- if (content::IsDeadlineSchedulingEnabled())
- command_line->AppendSwitch(switches::kEnableDeadlineScheduling);
-
GetContentClient()->browser()->AppendExtraCommandLineSwitches(
command_line, GetID());
- // Appending disable-gpu-feature switches due to software rendering list.
- GpuDataManagerImpl* gpu_data_manager = GpuDataManagerImpl::GetInstance();
- DCHECK(gpu_data_manager);
- gpu_data_manager->AppendRendererCommandLine(command_line);
+ if (content::IsPinchToZoomEnabled())
+ command_line->AppendSwitch(switches::kEnablePinch);
+
+#if defined(OS_WIN)
+ command_line->AppendSwitchASCII(switches::kDeviceScaleFactor,
+ base::DoubleToString(gfx::GetDPIScale()));
+#endif
+
+ AppendCompositorCommandLineFlags(command_line);
}
void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
@@ -922,116 +1080,102 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
// Propagate the following switches to the renderer command line (along
// with any associated values) if present in the browser command line.
static const char* const kSwitchNames[] = {
+ switches::kAllowInsecureWebSocketFromHttpsOrigin,
+ switches::kAllowLoopbackInPeerConnection,
switches::kAudioBufferSize,
switches::kAuditAllHandles,
switches::kAuditHandles,
+ switches::kBlinkPlatformLogChannels,
switches::kBlockCrossSiteDocuments,
switches::kDefaultTileWidth,
switches::kDefaultTileHeight,
switches::kDisable3DAPIs,
- switches::kDisableAcceleratedCompositing,
switches::kDisableAcceleratedFixedRootBackground,
- switches::kDisableAcceleratedScrollableFrames,
+ switches::kDisableAcceleratedOverflowScroll,
switches::kDisableAcceleratedVideoDecode,
switches::kDisableApplicationCache,
- switches::kDisableAudio,
switches::kDisableBreakpad,
- switches::kDisableCompositedScrollingForFrames,
switches::kDisableCompositingForFixedPosition,
switches::kDisableCompositingForTransition,
switches::kDisableDatabases,
- switches::kDisableDeadlineScheduling,
- switches::kDisableDelegatedRenderer,
switches::kDisableDesktopNotifications,
- switches::kDisableDeviceMotion,
- switches::kDisableDeviceOrientation,
switches::kDisableDirectNPAPIRequests,
+ switches::kDisableDistanceFieldText,
+ switches::kDisableFastTextAutosizing,
switches::kDisableFileSystem,
- switches::kDisableFiltersOverIPC,
- switches::kDisableFullScreen,
- switches::kDisableGeolocation,
- switches::kDisableGpu,
switches::kDisableGpuCompositing,
switches::kDisableGpuVsync,
+ switches::kDisableLowResTiling,
switches::kDisableHistogramCustomizer,
+ switches::kDisableLCDText,
switches::kDisableLayerSquashing,
switches::kDisableLocalStorage,
switches::kDisableLogging,
- switches::kDisableOpusPlayback,
+ switches::kDisableMediaSource,
+ switches::kDisableOverlayScrollbar,
switches::kDisablePinch,
switches::kDisablePrefixedEncryptedMedia,
+ switches::kDisableRepaintAfterLayout,
switches::kDisableSeccompFilterSandbox,
switches::kDisableSessionStorage,
switches::kDisableSharedWorkers,
- switches::kDisableSpeechInput,
- switches::kDisableThreadedCompositing,
switches::kDisableTouchAdjustment,
switches::kDisableTouchDragDrop,
switches::kDisableTouchEditing,
- switches::kDisableUniversalAcceleratedOverflowScroll,
- switches::kDisableUnprefixedMediaSource,
- switches::kDisableVp8AlphaPlayback,
- switches::kDisableWebAnimationsCSS,
- switches::kDisableWebKitMediaSource,
+ switches::kDisableZeroCopy,
switches::kDomAutomationController,
switches::kEnableAcceleratedFixedRootBackground,
switches::kEnableAcceleratedOverflowScroll,
- switches::kEnableAcceleratedScrollableFrames,
- switches::kEnableAccessibilityLogging,
switches::kEnableBeginFrameScheduling,
- switches::kEnableBrowserPluginForAllViewTypes,
- switches::kEnableCompositedScrollingForFrames,
+ switches::kEnableBleedingEdgeRenderingFastPaths,
switches::kEnableCompositingForFixedPosition,
switches::kEnableCompositingForTransition,
- switches::kEnableDCHECK,
- switches::kEnableDeadlineScheduling,
switches::kEnableDeferredImageDecoding,
- switches::kEnableDelegatedRenderer,
- switches::kEnableEac3Playback,
+ switches::kEnableDistanceFieldText,
switches::kEnableEncryptedMedia,
switches::kEnableExperimentalCanvasFeatures,
switches::kEnableExperimentalWebPlatformFeatures,
- switches::kEnableExperimentalWebSocket,
switches::kEnableFastTextAutosizing,
- switches::kEnableGpuBenchmarking,
switches::kEnableGPUClientLogging,
switches::kEnableGpuClientTracing,
switches::kEnableGPUServiceLogging,
switches::kEnableHighDpiCompositingForFixedPosition,
- switches::kEnableHTMLImports,
+ switches::kEnableLowResTiling,
switches::kEnableInbandTextTracks,
- switches::kEnableInputModeAttribute,
+ switches::kEnableLCDText,
switches::kEnableLayerSquashing,
switches::kEnableLogging,
- switches::kEnableMP3StreamParser,
switches::kEnableMemoryBenchmarking,
+ switches::kEnableOneCopy,
switches::kEnableOverlayFullscreenVideo,
- switches::kEnableOverlayScrollbars,
+ switches::kEnableOverlayScrollbar,
switches::kEnableOverscrollNotifications,
switches::kEnablePinch,
+ switches::kEnablePreciseMemoryInfo,
switches::kEnablePreparsedJsCaching,
- switches::kEnablePruneGpuCommandBuffers,
switches::kEnableRepaintAfterLayout,
+ switches::kEnableSeccompFilterSandbox,
switches::kEnableServiceWorker,
switches::kEnableSkiaBenchmarking,
- switches::kEnableSoftwareCompositing,
switches::kEnableSpeechSynthesis,
switches::kEnableStatsTable,
switches::kEnableStrictSiteIsolation,
- switches::kEnableThreadedCompositing,
- switches::kEnableUniversalAcceleratedOverflowScroll,
+ switches::kEnableTargetedStyleRecalc,
switches::kEnableTouchDragDrop,
switches::kEnableTouchEditing,
switches::kEnableViewport,
switches::kEnableViewportMeta,
switches::kMainFrameResizesAreOrientationChanges,
switches::kEnableVtune,
- switches::kEnableWebAnimationsCSS,
switches::kEnableWebAnimationsSVG,
switches::kEnableWebGLDraftExtensions,
+ switches::kEnableWebGLImageChromium,
switches::kEnableWebMIDI,
+ switches::kEnableZeroCopy,
switches::kForceDeviceScaleFactor,
switches::kFullMemoryCrashReport,
+ switches::kIgnoreResolutionLimitsForAcceleratedVideoDecode,
+ switches::kIPCConnectionTimeout,
switches::kJavaScriptFlags,
switches::kLoggingLevel,
switches::kMaxUntiledLayerWidth,
@@ -1039,6 +1183,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kMemoryMetrics,
switches::kNoReferrers,
switches::kNoSandbox,
+ switches::kNumRasterThreads,
switches::kPpapiInProcess,
switches::kProfilerTiming,
switches::kReduceSecurityForTesting,
@@ -1048,40 +1193,30 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kShowPaintRects,
switches::kSitePerProcess,
switches::kStatsCollectionController,
- switches::kTestSandbox,
+ switches::kTestType,
switches::kTouchEvents,
switches::kTraceToConsole,
+ switches::kUseDiscardableMemory,
// This flag needs to be propagated to the renderer process for
// --in-process-webgl.
switches::kUseGL,
switches::kUseMobileUserAgent,
- switches::kUserAgent,
switches::kV,
switches::kVideoThreads,
switches::kVModule,
- switches::kWebCoreLogChannels,
- switches::kWebGLCommandBufferSizeKb,
// Please keep these in alphabetical order. Compositor switches here should
// also be added to chrome/browser/chromeos/login/chrome_restart_request.cc.
- cc::switches::kBackgroundColorInsteadOfCheckerboard,
cc::switches::kCompositeToMailbox,
cc::switches::kDisableCompositedAntialiasing,
cc::switches::kDisableCompositorTouchHitTesting,
- cc::switches::kDisableImplSidePainting,
- cc::switches::kDisableLCDText,
- cc::switches::kDisableMapImage,
+ cc::switches::kDisableMainFrameBeforeActivation,
+ cc::switches::kDisableMainFrameBeforeDraw,
cc::switches::kDisableThreadedAnimation,
- cc::switches::kEnableGPURasterization,
- cc::switches::kEnableImplSidePainting,
- cc::switches::kEnableLCDText,
- cc::switches::kEnableMapImage,
- cc::switches::kEnablePartialSwap,
- cc::switches::kEnablePerTilePainting,
- cc::switches::kEnablePinchVirtualViewport,
+ cc::switches::kEnableGpuBenchmarking,
+ cc::switches::kEnableMainFrameBeforeActivation,
cc::switches::kEnableTopControlsPositionCalculation,
cc::switches::kMaxTilesForInterestArea,
cc::switches::kMaxUnusedResourceMemoryUsagePercentage,
- cc::switches::kNumRasterThreads,
cc::switches::kShowCompositedLayerBorders,
cc::switches::kShowFPSCounter,
cc::switches::kShowLayerAnimationBounds,
@@ -1096,28 +1231,15 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
cc::switches::kTopControlsHeight,
cc::switches::kTopControlsHideThreshold,
cc::switches::kTopControlsShowThreshold,
- cc::switches::kTraceOverdraw,
#if defined(ENABLE_PLUGINS)
switches::kEnablePepperTesting,
- switches::kDisablePepper3d,
#endif
#if defined(ENABLE_WEBRTC)
- switches::kEnableAudioTrackProcessing,
+ switches::kDisableAudioTrackProcessing,
switches::kDisableDeviceEnumeration,
- switches::kDisableSCTPDataChannels,
switches::kDisableWebRtcHWDecoding,
switches::kDisableWebRtcHWEncoding,
- switches::kEnableWebRtcAecRecordings,
switches::kEnableWebRtcHWVp8Encoding,
- switches::kEnableWebRtcTcpServerSocket,
-#endif
-#if !defined (GOOGLE_CHROME_BUILD)
- // These are unsupported and not fully tested modes, so don't enable them
- // for official Google Chrome builds.
- switches::kInProcessPlugins,
-#endif // GOOGLE_CHROME_BUILD
-#if defined(GOOGLE_TV)
- switches::kUseExternalVideoSurfaceThresholdInPixels,
#endif
#if defined(OS_ANDROID)
switches::kDisableGestureRequirementForMediaPlayback,
@@ -1125,26 +1247,16 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kDisableWebRTC,
switches::kEnableLowEndDeviceMode,
switches::kEnableSpeechRecognition,
- switches::kHideScrollbars,
switches::kMediaDrmEnableNonCompositing,
switches::kNetworkCountryIso,
-#endif
-#if defined(OS_ANDROID) && defined(ARCH_CPU_X86)
- switches::kEnableWebAudio,
-#else
- // Need to be able to disable webaudio on other platforms where it
- // is enabled by default.
switches::kDisableWebAudio,
#endif
#if defined(OS_MACOSX)
// Allow this to be set when invoking the browser and relayed along.
switches::kEnableSandboxLogging,
#endif
-#if defined(OS_POSIX)
- switches::kChildCleanExit,
-#endif
#if defined(OS_WIN)
- switches::kEnableDirectWrite,
+ switches::kDisableDirectWrite,
switches::kEnableHighResolutionTime,
#endif
};
@@ -1164,13 +1276,10 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
if (GetBrowserContext()->IsOffTheRecord() &&
!browser_cmd.HasSwitch(switches::kDisableDatabases)) {
renderer_cmd->AppendSwitch(switches::kDisableDatabases);
-#if defined(OS_ANDROID)
- renderer_cmd->AppendSwitch(switches::kDisableMediaHistoryLogging);
-#endif
}
// Enforce the extra command line flags for impl-side painting.
- if (cc::switches::IsImplSidePaintingEnabled() &&
+ if (IsImplSidePaintingEnabled() &&
!browser_cmd.HasSwitch(switches::kEnableDeferredImageDecoding))
renderer_cmd->AppendSwitch(switches::kEnableDeferredImageDecoding);
}
@@ -1205,6 +1314,12 @@ bool RenderProcessHostImpl::FastShutdownIfPossible() {
if (!SuddenTerminationAllowed())
return false;
+ if (worker_ref_count_ != 0) {
+ if (survive_for_worker_start_time_.is_null())
+ survive_for_worker_start_time_ = base::TimeTicks::Now();
+ return false;
+ }
+
// Set this before ProcessDied() so observers can tell if the render process
// died due to fast shutdown versus another cause.
fast_shutdown_started_ = true;
@@ -1216,89 +1331,13 @@ bool RenderProcessHostImpl::FastShutdownIfPossible() {
void RenderProcessHostImpl::DumpHandles() {
#if defined(OS_WIN)
Send(new ChildProcessMsg_DumpHandles());
- return;
-#endif
-
- NOTIMPLEMENTED();
-}
-
-// This is a platform specific function for mapping a transport DIB given its id
-TransportDIB* RenderProcessHostImpl::MapTransportDIB(
- TransportDIB::Id dib_id) {
-#if defined(OS_WIN)
- // On Windows we need to duplicate the handle from the remote process
- HANDLE section;
- DuplicateHandle(GetHandle(), dib_id.handle, GetCurrentProcess(), &section,
- STANDARD_RIGHTS_REQUIRED | FILE_MAP_READ | FILE_MAP_WRITE,
- FALSE, 0);
- return TransportDIB::Map(section);
-#elif defined(TOOLKIT_GTK)
- return TransportDIB::Map(dib_id.shmkey);
-#elif defined(OS_ANDROID)
- return TransportDIB::Map(dib_id);
-#else
- // On POSIX, the browser allocates all DIBs and keeps a file descriptor around
- // for each.
- return widget_helper_->MapTransportDIB(dib_id);
-#endif
-}
-
-TransportDIB* RenderProcessHostImpl::GetTransportDIB(
- TransportDIB::Id dib_id) {
- if (!TransportDIB::is_valid_id(dib_id))
- return NULL;
-
- const std::map<TransportDIB::Id, TransportDIB*>::iterator
- i = cached_dibs_.find(dib_id);
- if (i != cached_dibs_.end()) {
- cached_dibs_cleaner_.Reset();
- return i->second;
- }
-
- TransportDIB* dib = MapTransportDIB(dib_id);
- if (!dib)
- return NULL;
-
- if (cached_dibs_.size() >= MAX_MAPPED_TRANSPORT_DIBS) {
- // Clean a single entry from the cache
- std::map<TransportDIB::Id, TransportDIB*>::iterator smallest_iterator;
- size_t smallest_size = std::numeric_limits<size_t>::max();
-
- for (std::map<TransportDIB::Id, TransportDIB*>::iterator
- i = cached_dibs_.begin(); i != cached_dibs_.end(); ++i) {
- if (i->second->size() <= smallest_size) {
- smallest_iterator = i;
- smallest_size = i->second->size();
- }
- }
-
-#if defined(TOOLKIT_GTK)
- smallest_iterator->second->Detach();
-#else
- delete smallest_iterator->second;
-#endif
- cached_dibs_.erase(smallest_iterator);
- }
-
- cached_dibs_[dib_id] = dib;
- cached_dibs_cleaner_.Reset();
- return dib;
-}
-
-void RenderProcessHostImpl::ClearTransportDIBCache() {
-#if defined(TOOLKIT_GTK)
- std::map<TransportDIB::Id, TransportDIB*>::const_iterator dib =
- cached_dibs_.begin();
- for (; dib != cached_dibs_.end(); ++dib)
- dib->second->Detach();
#else
- STLDeleteContainerPairSecondPointers(
- cached_dibs_.begin(), cached_dibs_.end());
+ NOTIMPLEMENTED();
#endif
- cached_dibs_.clear();
}
bool RenderProcessHostImpl::Send(IPC::Message* msg) {
+ TRACE_EVENT0("renderer_host", "RenderProcessHostImpl::Send");
if (!channel_) {
if (!is_initialized_) {
queued_messages_.push(msg);
@@ -1327,8 +1366,7 @@ bool RenderProcessHostImpl::OnMessageReceived(const IPC::Message& msg) {
mark_child_process_activity_time();
if (msg.routing_id() == MSG_ROUTING_CONTROL) {
// Dispatch control messages.
- bool msg_is_ok = true;
- IPC_BEGIN_MESSAGE_MAP_EX(RenderProcessHostImpl, msg, msg_is_ok)
+ IPC_BEGIN_MESSAGE_MAP(RenderProcessHostImpl, msg)
IPC_MESSAGE_HANDLER(ChildProcessHostMsg_ShutdownRequest,
OnShutdownRequest)
IPC_MESSAGE_HANDLER(ChildProcessHostMsg_DumpHandlesDone,
@@ -1338,18 +1376,21 @@ bool RenderProcessHostImpl::OnMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_HANDLER(ViewHostMsg_UserMetricsRecordAction,
OnUserMetricsRecordAction)
IPC_MESSAGE_HANDLER(ViewHostMsg_SavedPageAsMHTML, OnSavedPageAsMHTML)
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(
+ ChildProcessHostMsg_SyncAllocateGpuMemoryBuffer,
+ OnAllocateGpuMemoryBuffer)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_Close_ACK, OnCloseACK)
+#if defined(ENABLE_WEBRTC)
+ IPC_MESSAGE_HANDLER(AecDumpMsg_RegisterAecDumpConsumer,
+ OnRegisterAecDumpConsumer)
+ IPC_MESSAGE_HANDLER(AecDumpMsg_UnregisterAecDumpConsumer,
+ OnUnregisterAecDumpConsumer)
+#endif
// Adding single handlers for your service here is fine, but once your
// service needs more than one handler, please extract them into a new
// message filter and add that filter to CreateMessageFilters().
- IPC_END_MESSAGE_MAP_EX()
-
- if (!msg_is_ok) {
- // The message had a handler, but its de-serialization failed.
- // We consider this a capital crime. Kill the renderer if we have one.
- LOG(ERROR) << "bad message " << msg.type() << " terminating renderer.";
- RecordAction(UserMetricsAction("BadMessageTerminate_BRPH"));
- ReceivedBadMessage();
- }
+ IPC_END_MESSAGE_MAP()
+
return true;
}
@@ -1366,11 +1407,10 @@ bool RenderProcessHostImpl::OnMessageReceived(const IPC::Message& msg) {
// If this is a SwapBuffers, we need to ack it if we're not going to handle
// it so that the GPU process doesn't get stuck in unscheduled state.
- bool msg_is_ok = true;
- IPC_BEGIN_MESSAGE_MAP_EX(RenderProcessHostImpl, msg, msg_is_ok)
+ IPC_BEGIN_MESSAGE_MAP(RenderProcessHostImpl, msg)
IPC_MESSAGE_HANDLER(ViewHostMsg_CompositorSurfaceBuffersSwapped,
OnCompositorSurfaceBuffersSwappedNoHost)
- IPC_END_MESSAGE_MAP_EX()
+ IPC_END_MESSAGE_MAP()
return true;
}
return listener->OnMessageReceived(msg);
@@ -1385,14 +1425,21 @@ void RenderProcessHostImpl::OnChannelConnected(int32 peer_pid) {
tracked_objects::ThreadData::Status status =
tracked_objects::ThreadData::status();
Send(new ChildProcessMsg_SetProfilerStatus(status));
-
- Send(new ViewMsg_SetRendererProcessID(GetID()));
}
void RenderProcessHostImpl::OnChannelError() {
ProcessDied(true /* already_dead */);
}
+void RenderProcessHostImpl::OnBadMessageReceived(const IPC::Message& message) {
+ // Message de-serialization failed. We consider this a capital crime. Kill the
+ // renderer if we have one.
+ LOG(ERROR) << "bad message " << message.type() << " terminating renderer.";
+ BrowserChildProcessHostImpl::HistogramBadMessageTerminated(
+ PROCESS_TYPE_RENDERER);
+ ReceivedBadMessage();
+}
+
BrowserContext* RenderProcessHostImpl::GetBrowserContext() const {
return browser_context_;
}
@@ -1419,8 +1466,34 @@ bool RenderProcessHostImpl::IgnoreInputEvents() const {
}
void RenderProcessHostImpl::Cleanup() {
+ // If within_process_died_observer_ is true, one of our observers performed an
+ // action that caused us to die (e.g. http://crbug.com/339504). Therefore,
+ // delay the destruction until all of the observer callbacks have been made,
+ // and guarantee that the RenderProcessHostDestroyed observer callback is
+ // always the last callback fired.
+ if (within_process_died_observer_) {
+ delayed_cleanup_needed_ = true;
+ return;
+ }
+ delayed_cleanup_needed_ = false;
+
+ // Records the time when the process starts surviving for workers for UMA.
+ if (listeners_.IsEmpty() && worker_ref_count_ > 0 &&
+ survive_for_worker_start_time_.is_null()) {
+ survive_for_worker_start_time_ = base::TimeTicks::Now();
+ }
+
// When there are no other owners of this object, we can delete ourselves.
- if (listeners_.IsEmpty()) {
+ if (listeners_.IsEmpty() && worker_ref_count_ == 0) {
+ if (!survive_for_worker_start_time_.is_null()) {
+ UMA_HISTOGRAM_LONG_TIMES(
+ "SharedWorker.RendererSurviveForWorkerTime",
+ base::TimeTicks::Now() - survive_for_worker_start_time_);
+ }
+ // We cannot clean up twice; if this fails, there is an issue with our
+ // control flow.
+ DCHECK(!deleting_soon_);
+
DCHECK_EQ(0, pending_views_);
FOR_EACH_OBSERVER(RenderProcessHostObserver,
observers_,
@@ -1443,7 +1516,7 @@ void RenderProcessHostImpl::Cleanup() {
channel_.reset();
gpu_message_filter_ = NULL;
message_port_message_filter_ = NULL;
- geolocation_dispatcher_host_ = NULL;
+ RemoveUserData(kSessionStorageHolderKey);
// Remove ourself from the list of renderer processes so that we can't be
// reused in between now and when the Delete task runs.
@@ -1472,19 +1545,66 @@ base::TimeDelta RenderProcessHostImpl::GetChildProcessIdleTime() const {
return base::TimeTicks::Now() - child_process_activity_time_;
}
-void RenderProcessHostImpl::SurfaceUpdated(int32 surface_id) {
- if (!gpu_message_filter_)
- return;
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
- &GpuMessageFilter::SurfaceUpdated,
- gpu_message_filter_,
- surface_id));
-}
-
void RenderProcessHostImpl::ResumeRequestsForView(int route_id) {
widget_helper_->ResumeRequestsForView(route_id);
}
+void RenderProcessHostImpl::FilterURL(bool empty_allowed, GURL* url) {
+ FilterURL(this, empty_allowed, url);
+}
+
+#if defined(ENABLE_WEBRTC)
+void RenderProcessHostImpl::EnableAecDump(const base::FilePath& file) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ // Enable AEC dump for each registered consumer.
+ for (std::vector<int>::iterator it = aec_dump_consumers_.begin();
+ it != aec_dump_consumers_.end(); ++it) {
+ EnableAecDumpForId(file, *it);
+ }
+}
+
+void RenderProcessHostImpl::DisableAecDump() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ // Posting on the FILE thread and then replying back on the UI thread is only
+ // for avoiding races between enable and disable. Nothing is done on the FILE
+ // thread.
+ BrowserThread::PostTaskAndReply(
+ BrowserThread::FILE, FROM_HERE,
+ base::Bind(&DisableAecDumpOnFileThread),
+ base::Bind(&RenderProcessHostImpl::SendDisableAecDumpToRenderer,
+ weak_factory_.GetWeakPtr()));
+}
+
+void RenderProcessHostImpl::SetWebRtcLogMessageCallback(
+ base::Callback<void(const std::string&)> callback) {
+ webrtc_log_message_callback_ = callback;
+}
+
+RenderProcessHostImpl::WebRtcStopRtpDumpCallback
+RenderProcessHostImpl::StartRtpDump(
+ bool incoming,
+ bool outgoing,
+ const WebRtcRtpPacketCallback& packet_callback) {
+ if (!p2p_socket_dispatcher_host_)
+ return WebRtcStopRtpDumpCallback();
+
+ BrowserThread::PostTask(BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&P2PSocketDispatcherHost::StartRtpDump,
+ p2p_socket_dispatcher_host_,
+ incoming,
+ outgoing,
+ packet_callback));
+
+ if (stop_rtp_dump_callback_.is_null()) {
+ stop_rtp_dump_callback_ =
+ base::Bind(&P2PSocketDispatcherHost::StopRtpDumpOnUIThread,
+ p2p_socket_dispatcher_host_);
+ }
+ return stop_rtp_dump_callback_;
+}
+#endif
+
IPC::ChannelProxy* RenderProcessHostImpl::GetChannel() {
return channel_.get();
}
@@ -1525,6 +1645,53 @@ void RenderProcessHostImpl::UnregisterHost(int host_id) {
}
// static
+void RenderProcessHostImpl::FilterURL(RenderProcessHost* rph,
+ bool empty_allowed,
+ GURL* url) {
+ ChildProcessSecurityPolicyImpl* policy =
+ ChildProcessSecurityPolicyImpl::GetInstance();
+
+ if (empty_allowed && url->is_empty())
+ return;
+
+ // The browser process should never hear the swappedout:// URL from any
+ // of the renderer's messages. Check for this in debug builds, but don't
+ // let it crash a release browser.
+ DCHECK(GURL(kSwappedOutURL) != *url);
+
+ if (!url->is_valid()) {
+ // Have to use about:blank for the denied case, instead of an empty GURL.
+ // This is because the browser treats navigation to an empty GURL as a
+ // navigation to the home page. This is often a privileged page
+ // (chrome://newtab/) which is exactly what we don't want.
+ *url = GURL(url::kAboutBlankURL);
+ RecordAction(base::UserMetricsAction("FilterURLTermiate_Invalid"));
+ return;
+ }
+
+ if (url->SchemeIs(url::kAboutScheme)) {
+ // The renderer treats all URLs in the about: scheme as being about:blank.
+ // Canonicalize about: URLs to about:blank.
+ *url = GURL(url::kAboutBlankURL);
+ RecordAction(base::UserMetricsAction("FilterURLTermiate_About"));
+ }
+
+ // Do not allow browser plugin guests to navigate to non-web URLs, since they
+ // cannot swap processes or grant bindings.
+ bool non_web_url_in_guest = rph->IsIsolatedGuest() &&
+ !(url->is_valid() && policy->IsWebSafeScheme(url->scheme()));
+
+ if (non_web_url_in_guest || !policy->CanRequestURL(rph->GetID(), *url)) {
+ // If this renderer is not permitted to request this URL, we invalidate the
+ // URL. This prevents us from storing the blocked URL and becoming confused
+ // later.
+ VLOG(1) << "Blocked URL " << url->spec();
+ *url = GURL(url::kAboutBlankURL);
+ RecordAction(base::UserMetricsAction("FilterURLTermiate_Blocked"));
+ }
+}
+
+// static
bool RenderProcessHostImpl::IsSuitableHost(
RenderProcessHost* host,
BrowserContext* browser_context,
@@ -1539,7 +1706,7 @@ bool RenderProcessHostImpl::IsSuitableHost(
// and non-guest storage gets mixed. In the future, we might consider enabling
// the sharing of guests, in this case this check should be removed and
// InSameStoragePartition should handle the possible sharing.
- if (host->IsGuest())
+ if (host->IsIsolatedGuest())
return false;
// Check whether the given host and the intended site_url will be using the
@@ -1570,24 +1737,30 @@ void RenderProcessHost::SetRunRendererInProcess(bool value) {
g_run_renderer_in_process_ = value;
CommandLine* command_line = CommandLine::ForCurrentProcess();
- if (value && !command_line->HasSwitch(switches::kLang)) {
- // Modify the current process' command line to include the browser locale,
- // as the renderer expects this flag to be set.
- const std::string locale =
- GetContentClient()->browser()->GetApplicationLocale();
- command_line->AppendSwitchASCII(switches::kLang, locale);
+ if (value) {
+ if (!command_line->HasSwitch(switches::kLang)) {
+ // Modify the current process' command line to include the browser locale,
+ // as the renderer expects this flag to be set.
+ const std::string locale =
+ GetContentClient()->browser()->GetApplicationLocale();
+ command_line->AppendSwitchASCII(switches::kLang, locale);
+ }
+ // TODO(piman): we should really send configuration through bools rather
+ // than by parsing strings, i.e. sending an IPC rather than command line
+ // args. crbug.com/314909
+ AppendCompositorCommandLineFlags(command_line);
}
}
// static
RenderProcessHost::iterator RenderProcessHost::AllHostsIterator() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
return iterator(g_all_hosts.Pointer());
}
// static
RenderProcessHost* RenderProcessHost::FromID(int render_process_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
return g_all_hosts.Get().Lookup(render_process_id);
}
@@ -1630,11 +1803,12 @@ RenderProcessHost* RenderProcessHost::GetExistingProcessHost(
iterator iter(AllHostsIterator());
while (!iter.IsAtEnd()) {
- if (RenderProcessHostImpl::IsSuitableHost(
+ if (GetContentClient()->browser()->MayReuseHost(iter.GetCurrentValue()) &&
+ RenderProcessHostImpl::IsSuitableHost(
iter.GetCurrentValue(),
- browser_context, site_url))
+ browser_context, site_url)) {
suitable_renderers.push_back(iter.GetCurrentValue());
-
+ }
iter.Advance();
}
@@ -1665,7 +1839,7 @@ bool RenderProcessHost::ShouldUseProcessPerSite(
// Note: DevTools pages have WebUI type but should not reuse the same host.
if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL(
browser_context, url) &&
- !url.SchemeIs(chrome::kChromeDevToolsScheme)) {
+ !url.SchemeIs(kChromeDevToolsScheme)) {
return true;
}
@@ -1687,10 +1861,12 @@ RenderProcessHost* RenderProcessHostImpl::GetProcessHostForSite(
std::string site = SiteInstance::GetSiteForURL(browser_context, url)
.possibly_invalid_spec();
RenderProcessHost* host = map->FindProcess(site);
- if (host && !IsSuitableHost(host, browser_context, url)) {
+ if (host && (!GetContentClient()->browser()->MayReuseHost(host) ||
+ !IsSuitableHost(host, browser_context, url))) {
// The registered process does not have an appropriate set of bindings for
// the url. Remove it from the map so we can register a better one.
- RecordAction(UserMetricsAction("BindingsMismatch_GetProcessHostPerSite"));
+ RecordAction(
+ base::UserMetricsAction("BindingsMismatch_GetProcessHostPerSite"));
map->RemoveProcess(host);
host = NULL;
}
@@ -1722,6 +1898,13 @@ void RenderProcessHostImpl::ProcessDied(bool already_dead) {
// calls to a renderer. If we don't have a valid channel here it means we
// already handled the error.
+ // It should not be possible for us to be called re-entrantly.
+ DCHECK(!within_process_died_observer_);
+
+ // It should not be possible for a process death notification to come in while
+ // we are dying.
+ DCHECK(!deleting_soon_);
+
// child_process_launcher_ can be NULL in single process mode or if fast
// termination happened.
int exit_code = 0;
@@ -1732,16 +1915,21 @@ void RenderProcessHostImpl::ProcessDied(bool already_dead) {
base::TERMINATION_STATUS_NORMAL_TERMINATION;
RendererClosedDetails details(GetHandle(), status, exit_code);
+ within_process_died_observer_ = true;
NotificationService::current()->Notify(
NOTIFICATION_RENDERER_PROCESS_CLOSED,
Source<RenderProcessHost>(this),
Details<RendererClosedDetails>(&details));
+ FOR_EACH_OBSERVER(RenderProcessHostObserver,
+ observers_,
+ RenderProcessExited(this, GetHandle(), status, exit_code));
+ within_process_died_observer_ = false;
child_process_launcher_.reset();
channel_.reset();
gpu_message_filter_ = NULL;
message_port_message_filter_ = NULL;
- geolocation_dispatcher_host_ = NULL;
+ RemoveUserData(kSessionStorageHolderKey);
IDMap<IPC::Listener>::iterator iter(&listeners_);
while (!iter.IsAtEnd()) {
@@ -1752,9 +1940,14 @@ void RenderProcessHostImpl::ProcessDied(bool already_dead) {
iter.Advance();
}
- ClearTransportDIBCache();
+ mojo_application_host_.reset();
+
+ // It's possible that one of the calls out to the observers might have caused
+ // this object to be no longer needed.
+ if (delayed_cleanup_needed_)
+ Cleanup();
- // this object is not deleted at this point and may be reused later.
+ // This object is not deleted at this point and might be reused later.
// TODO(darin): clean this up
}
@@ -1792,6 +1985,32 @@ void RenderProcessHostImpl::EndFrameSubscription(int route_id) {
route_id));
}
+#if defined(ENABLE_WEBRTC)
+void RenderProcessHostImpl::WebRtcLogMessage(const std::string& message) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (!webrtc_log_message_callback_.is_null())
+ webrtc_log_message_callback_.Run(message);
+}
+#endif
+
+void RenderProcessHostImpl::ReleaseOnCloseACK(
+ RenderProcessHost* host,
+ const SessionStorageNamespaceMap& sessions,
+ int view_route_id) {
+ DCHECK(host);
+ if (sessions.empty())
+ return;
+ SessionStorageHolder* holder = static_cast<SessionStorageHolder*>
+ (host->GetUserData(kSessionStorageHolderKey));
+ if (!holder) {
+ holder = new SessionStorageHolder();
+ host->SetUserData(
+ kSessionStorageHolderKey,
+ holder);
+ }
+ holder->Hold(sessions, view_route_id);
+}
+
void RenderProcessHostImpl::OnShutdownRequest() {
// Don't shut down if there are active RenderViews, or if there are pending
// RenderViews being swapped back in.
@@ -1826,6 +2045,10 @@ void RenderProcessHostImpl::SetBackgrounded(bool backgrounded) {
if (!child_process_launcher_.get() || child_process_launcher_->IsStarting())
return;
+ // Don't background processes which have active audio streams.
+ if (backgrounded_ && audio_renderer_host_->HasActiveAudio())
+ return;
+
#if defined(OS_WIN)
// The cbstext.dll loads as a global GetMessage hook in the browser process
// and intercepts/unintercepts the kernel32 API SetPriorityClass in a
@@ -1837,7 +2060,17 @@ void RenderProcessHostImpl::SetBackgrounded(bool backgrounded) {
return;
#endif // OS_WIN
+ // Notify the child process of background state.
+ Send(new ChildProcessMsg_SetProcessBackgrounded(backgrounded));
+
+#if !defined(OS_WIN)
+ // Backgrounding may require elevated privileges not available to renderer
+ // processes, so control backgrounding from the process host.
+
+ // Windows Vista+ has a fancy process backgrounding mode that can only be set
+ // from within the process.
child_process_launcher_->SetProcessBackgrounded(backgrounded);
+#endif // !OS_WIN
}
void RenderProcessHostImpl::OnProcessLaunched() {
@@ -1854,7 +2087,7 @@ void RenderProcessHostImpl::OnProcessLaunched() {
return;
}
- child_process_launcher_->SetProcessBackgrounded(backgrounded_);
+ SetBackgrounded(backgrounded_);
}
// NOTE: This needs to be before sending queued messages because
@@ -1869,10 +2102,20 @@ void RenderProcessHostImpl::OnProcessLaunched() {
Source<RenderProcessHost>(this),
NotificationService::NoDetails());
+ // Allow Mojo to be setup before the renderer sees any Chrome IPC messages.
+ // This way, Mojo can be safely used from the renderer in response to any
+ // Chrome IPC message.
+ MaybeActivateMojo();
+
while (!queued_messages_.empty()) {
Send(queued_messages_.front());
queued_messages_.pop();
}
+
+#if defined(ENABLE_WEBRTC)
+ if (WebRTCInternals::GetInstance()->aec_dump_enabled())
+ EnableAecDump(WebRTCInternals::GetInstance()->aec_dump_file_path());
+#endif
}
scoped_refptr<AudioRendererHost>
@@ -1885,6 +2128,14 @@ void RenderProcessHostImpl::OnUserMetricsRecordAction(
RecordComputedAction(action);
}
+void RenderProcessHostImpl::OnCloseACK(int old_route_id) {
+ SessionStorageHolder* holder = static_cast<SessionStorageHolder*>
+ (GetUserData(kSessionStorageHolderKey));
+ if (!holder)
+ return;
+ holder->Release(old_route_id);
+}
+
void RenderProcessHostImpl::OnSavedPageAsMHTML(int job_id, int64 data_size) {
MHTMLGenerationManager::GetInstance()->MHTMLGenerated(job_id, data_size);
}
@@ -1893,6 +2144,9 @@ void RenderProcessHostImpl::OnCompositorSurfaceBuffersSwappedNoHost(
const ViewHostMsg_CompositorSurfaceBuffersSwapped_Params& params) {
TRACE_EVENT0("renderer_host",
"RenderWidgetHostImpl::OnCompositorSurfaceBuffersSwappedNoHost");
+ if (!ui::LatencyInfo::Verify(params.latency_info,
+ "ViewHostMsg_CompositorSurfaceBuffersSwapped"))
+ return;
AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
ack_params.sync_point = 0;
RenderWidgetHostImpl::AcknowledgeBufferPresent(params.route_id,
@@ -1917,4 +2171,207 @@ void RenderProcessHostImpl::OnGpuSwitching() {
}
}
+#if defined(ENABLE_WEBRTC)
+void RenderProcessHostImpl::OnRegisterAecDumpConsumer(int id) {
+ BrowserThread::PostTask(
+ BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(
+ &RenderProcessHostImpl::RegisterAecDumpConsumerOnUIThread,
+ weak_factory_.GetWeakPtr(),
+ id));
+}
+
+void RenderProcessHostImpl::OnUnregisterAecDumpConsumer(int id) {
+ BrowserThread::PostTask(
+ BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(
+ &RenderProcessHostImpl::UnregisterAecDumpConsumerOnUIThread,
+ weak_factory_.GetWeakPtr(),
+ id));
+}
+
+void RenderProcessHostImpl::RegisterAecDumpConsumerOnUIThread(int id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ aec_dump_consumers_.push_back(id);
+ if (WebRTCInternals::GetInstance()->aec_dump_enabled()) {
+ EnableAecDumpForId(WebRTCInternals::GetInstance()->aec_dump_file_path(),
+ id);
+ }
+}
+
+void RenderProcessHostImpl::UnregisterAecDumpConsumerOnUIThread(int id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ for (std::vector<int>::iterator it = aec_dump_consumers_.begin();
+ it != aec_dump_consumers_.end(); ++it) {
+ if (*it == id) {
+ aec_dump_consumers_.erase(it);
+ break;
+ }
+ }
+}
+
+#if defined(OS_WIN)
+#define IntToStringType base::IntToString16
+#else
+#define IntToStringType base::IntToString
+#endif
+
+void RenderProcessHostImpl::EnableAecDumpForId(const base::FilePath& file,
+ int id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ base::FilePath unique_file =
+ file.AddExtension(IntToStringType(GetID()))
+ .AddExtension(IntToStringType(id));
+ BrowserThread::PostTaskAndReplyWithResult(
+ BrowserThread::FILE, FROM_HERE,
+ base::Bind(&CreateAecDumpFileForProcess, unique_file, GetHandle()),
+ base::Bind(&RenderProcessHostImpl::SendAecDumpFileToRenderer,
+ weak_factory_.GetWeakPtr(),
+ id));
+}
+
+#undef IntToStringType
+
+void RenderProcessHostImpl::SendAecDumpFileToRenderer(
+ int id,
+ IPC::PlatformFileForTransit file_for_transit) {
+ if (file_for_transit == IPC::InvalidPlatformFileForTransit())
+ return;
+ Send(new AecDumpMsg_EnableAecDump(id, file_for_transit));
+}
+
+void RenderProcessHostImpl::SendDisableAecDumpToRenderer() {
+ Send(new AecDumpMsg_DisableAecDump());
+}
+#endif
+
+void RenderProcessHostImpl::IncrementWorkerRefCount() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ ++worker_ref_count_;
+}
+
+void RenderProcessHostImpl::DecrementWorkerRefCount() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK_GT(worker_ref_count_, 0);
+ --worker_ref_count_;
+ if (worker_ref_count_ == 0)
+ Cleanup();
+}
+
+void RenderProcessHostImpl::ConnectTo(
+ const base::StringPiece& service_name,
+ mojo::ScopedMessagePipeHandle handle) {
+ mojo_activation_required_ = true;
+ MaybeActivateMojo();
+
+ mojo_application_host_->service_provider()->ConnectToService(
+ mojo::String::From(service_name),
+ std::string(),
+ handle.Pass(),
+ mojo::String());
+}
+
+void RenderProcessHostImpl::OnAllocateGpuMemoryBuffer(uint32 width,
+ uint32 height,
+ uint32 internalformat,
+ uint32 usage,
+ IPC::Message* reply) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (!GpuMemoryBufferImpl::IsFormatValid(internalformat) ||
+ !GpuMemoryBufferImpl::IsUsageValid(usage)) {
+ GpuMemoryBufferAllocated(reply, gfx::GpuMemoryBufferHandle());
+ return;
+ }
+ base::CheckedNumeric<int> size = width;
+ size *= height;
+ if (!size.IsValid()) {
+ GpuMemoryBufferAllocated(reply, gfx::GpuMemoryBufferHandle());
+ return;
+ }
+
+#if defined(OS_MACOSX)
+ // TODO(reveman): This should be moved to
+ // GpuMemoryBufferImpl::AllocateForChildProcess and
+ // GpuMemoryBufferImplIOSurface. crbug.com/325045, crbug.com/323304
+ if (GpuMemoryBufferImplIOSurface::IsConfigurationSupported(internalformat,
+ usage)) {
+ base::ScopedCFTypeRef<CFMutableDictionaryRef> properties;
+ properties.reset(
+ CFDictionaryCreateMutable(kCFAllocatorDefault,
+ 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks));
+ AddIntegerValue(properties, kIOSurfaceWidth, width);
+ AddIntegerValue(properties, kIOSurfaceHeight, height);
+ AddIntegerValue(properties,
+ kIOSurfaceBytesPerElement,
+ GpuMemoryBufferImpl::BytesPerPixel(internalformat));
+ AddIntegerValue(
+ properties,
+ kIOSurfacePixelFormat,
+ GpuMemoryBufferImplIOSurface::PixelFormat(internalformat));
+ // TODO(reveman): Remove this when using a mach_port_t to transfer
+ // IOSurface to renderer process. crbug.com/323304
+ AddBooleanValue(
+ properties, kIOSurfaceIsGlobal, true);
+
+ base::ScopedCFTypeRef<IOSurfaceRef> io_surface(IOSurfaceCreate(properties));
+ if (io_surface) {
+ gfx::GpuMemoryBufferHandle handle;
+ handle.type = gfx::IO_SURFACE_BUFFER;
+ handle.io_surface_id = IOSurfaceGetID(io_surface);
+
+ // TODO(reveman): This makes the assumption that the renderer will
+ // grab a reference to the surface before sending another message.
+ // crbug.com/325045
+ last_io_surface_ = io_surface;
+ GpuMemoryBufferAllocated(reply, handle);
+ return;
+ }
+ }
+#endif
+
+#if defined(OS_ANDROID)
+ // TODO(reveman): This should be moved to
+ // GpuMemoryBufferImpl::AllocateForChildProcess and
+ // GpuMemoryBufferImplSurfaceTexture when adding support for out-of-process
+ // GPU service. crbug.com/368716
+ if (GpuMemoryBufferImplSurfaceTexture::IsConfigurationSupported(
+ internalformat, usage)) {
+ // Each surface texture is associated with a render process id. This allows
+ // the GPU service and Java Binder IPC to verify that a renderer is not
+ // trying to use a surface texture it doesn't own.
+ int surface_texture_id = CompositorImpl::CreateSurfaceTexture(GetID());
+ if (surface_texture_id != -1) {
+ gfx::GpuMemoryBufferHandle handle;
+ handle.type = gfx::SURFACE_TEXTURE_BUFFER;
+ handle.surface_texture_id =
+ gfx::SurfaceTextureId(surface_texture_id, GetID());
+ GpuMemoryBufferAllocated(reply, handle);
+ return;
+ }
+ }
+#endif
+
+ GpuMemoryBufferImpl::AllocateForChildProcess(
+ gfx::Size(width, height),
+ internalformat,
+ usage,
+ GetHandle(),
+ base::Bind(&RenderProcessHostImpl::GpuMemoryBufferAllocated,
+ weak_factory_.GetWeakPtr(),
+ reply));
+}
+
+void RenderProcessHostImpl::GpuMemoryBufferAllocated(
+ IPC::Message* reply,
+ const gfx::GpuMemoryBufferHandle& handle) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ ChildProcessHostMsg_SyncAllocateGpuMemoryBuffer::WriteReplyParams(reply,
+ handle);
+ Send(reply);
+}
+
} // namespace content