This source file includes following definitions.
- reply_msg_
- filter
- reply_msg
- SendReplyAndDeleteThis
- context_
- GetPpapiChannelInfo
- OnPpapiChannelOpened
- OffTheRecord
- GetResourceContext
- routing_id_
- GetPpapiChannelInfo
- OnPpapiChannelOpened
- OffTheRecord
- AddBooleanValue
- AddIntegerValue
- sent_plugin_channel_request_
- ID
- GetResourceContext
- OffTheRecord
- SetPluginInfo
- OnFoundPluginProcessHost
- OnSentPluginChannelRequest
- OnChannelOpened
- OnError
- host
- sent_plugin_channel_request
- Cancel
- WriteReplyAndDeleteThis
- media_internals_
- OnChannelClosing
- OnChannelConnected
- OnMessageReceived
- OnDestruct
- OverrideTaskRunnerForMessage
- OffTheRecord
- OnCreateWindow
- OnCreateWidget
- OnCreateFullscreenWidget
- OnGetProcessMemorySizes
- OnSetCookie
- OnGetCookies
- OnGetRawCookies
- OnDeleteCookie
- OnCookiesEnabled
- OnLoadFont
- SendLoadFontReply
- OnGetPlugins
- GetPluginsCallback
- OnGetPluginInfo
- OnOpenChannelToPlugin
- OnOpenChannelToPepperPlugin
- OnDidCreateOutOfProcessPepperInstance
- OnDidDeleteOutOfProcessPepperInstance
- OnOpenChannelToPpapiBroker
- OnGenerateRoutingID
- OnGetCPUUsage
- OnGetAudioHardwareConfig
- OnGetMonitorColorProfile
- OnDownloadUrl
- OnCheckNotificationPermission
- OnAllocateSharedMemory
- OnAllocateSharedBitmap
- OnAllocatedSharedBitmap
- OnDeletedSharedBitmap
- GetCookieStoreForURL
- OnAllocTransportDIB
- OnFreeTransportDIB
- CheckPreparsedJsCachingEnabled
- OnCacheableMetadataAvailable
- OnKeygen
- PostKeygenToWorkerThread
- OnKeygenOnWorkerThread
- OnMediaLogEvents
- CheckPolicyForCookies
- SendGetCookiesResponse
- SendGetRawCookiesResponse
- OnCompletedOpenChannelToNpapiPlugin
- OnUpdateIsDelayed
- OnAre3DAPIsBlocked
- OnDidLose3DContext
- OnPreCacheFontCharacters
- OnWebAudioMediaCodec
- OnAllocateGpuMemoryBuffer
#include "content/browser/renderer_host/render_message_filter.h"
#include <map>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/debug/alias.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread.h"
#include "base/threading/worker_pool.h"
#include "content/browser/browser_main_loop.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/dom_storage/dom_storage_context_wrapper.h"
#include "content/browser/dom_storage/session_storage_namespace_impl.h"
#include "content/browser/download/download_stats.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/media/media_internals.h"
#include "content/browser/plugin_process_host.h"
#include "content/browser/plugin_service_impl.h"
#include "content/browser/ppapi_plugin_process_host.h"
#include "content/browser/renderer_host/pepper/pepper_security_helper.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/renderer_host/render_widget_helper.h"
#include "content/common/child_process_host_impl.h"
#include "content/common/child_process_messages.h"
#include "content/common/cookie_data.h"
#include "content/common/desktop_notification_messages.h"
#include "content/common/frame_messages.h"
#include "content/common/gpu/client/gpu_memory_buffer_impl.h"
#include "content/common/host_shared_bitmap_manager.h"
#include "content/common/media/media_param_traits.h"
#include "content/common/view_messages.h"
#include "content/public/browser/browser_child_process_host.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/download_save_info.h"
#include "content/public/browser/plugin_service_filter.h"
#include "content/public/browser/resource_context.h"
#include "content/public/browser/user_metrics.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/context_menu_params.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/webplugininfo.h"
#include "ipc/ipc_channel_handle.h"
#include "ipc/ipc_platform_file.h"
#include "media/audio/audio_manager.h"
#include "media/audio/audio_manager_base.h"
#include "media/audio/audio_parameters.h"
#include "media/base/media_log_event.h"
#include "net/base/io_buffer.h"
#include "net/base/keygen_handler.h"
#include "net/base/mime_util.h"
#include "net/base/request_priority.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_store.h"
#include "net/http/http_cache.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
#include "ppapi/shared_impl/file_type_conversion.h"
#include "third_party/WebKit/public/web/WebNotificationPresenter.h"
#include "ui/gfx/color_profile.h"
#if defined(OS_MACOSX)
#include "content/common/gpu/client/gpu_memory_buffer_impl_io_surface.h"
#include "content/common/mac/font_descriptor.h"
#include "ui/gl/io_surface_support_mac.h"
#else
#include "gpu/GLES2/gl2extchromium.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "third_party/khronos/GLES2/gl2ext.h"
#endif
#if defined(OS_POSIX)
#include "base/file_descriptor_posix.h"
#endif
#if defined(OS_WIN)
#include "content/common/font_cache_dispatcher_win.h"
#include "content/common/sandbox_win.h"
#endif
#if defined(OS_ANDROID)
#include "content/browser/renderer_host/compositor_impl_android.h"
#include "content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.h"
#include "media/base/android/webaudio_media_codec_bridge.h"
#endif
using net::CookieStore;
namespace content {
namespace {
#if defined(ENABLE_PLUGINS)
const int kPluginsRefreshThresholdInSeconds = 3;
#endif
static const int64 kCPUUsageSampleIntervalMs = 900;
const uint32 kFilteredMessageClasses[] = {
ChildProcessMsgStart,
DesktopNotificationMsgStart,
FrameMsgStart,
ViewMsgStart,
};
#if defined(OS_WIN)
base::LazyInstance<gfx::ColorProfile>::Leaky g_color_profile =
LAZY_INSTANCE_INITIALIZER;
#endif
class RenderMessageCompletionCallback {
public:
RenderMessageCompletionCallback(RenderMessageFilter* filter,
IPC::Message* reply_msg)
: filter_(filter),
reply_msg_(reply_msg) {
}
virtual ~RenderMessageCompletionCallback() {
}
RenderMessageFilter* filter() { return filter_.get(); }
IPC::Message* reply_msg() { return reply_msg_; }
void SendReplyAndDeleteThis() {
filter_->Send(reply_msg_);
delete this;
}
private:
scoped_refptr<RenderMessageFilter> filter_;
IPC::Message* reply_msg_;
};
class OpenChannelToPpapiPluginCallback
: public RenderMessageCompletionCallback,
public PpapiPluginProcessHost::PluginClient {
public:
OpenChannelToPpapiPluginCallback(RenderMessageFilter* filter,
ResourceContext* context,
IPC::Message* reply_msg)
: RenderMessageCompletionCallback(filter, reply_msg),
context_(context) {
}
virtual void GetPpapiChannelInfo(base::ProcessHandle* renderer_handle,
int* renderer_id) OVERRIDE {
*renderer_handle = filter()->PeerHandle();
*renderer_id = filter()->render_process_id();
}
virtual void OnPpapiChannelOpened(const IPC::ChannelHandle& channel_handle,
base::ProcessId plugin_pid,
int plugin_child_id) OVERRIDE {
ViewHostMsg_OpenChannelToPepperPlugin::WriteReplyParams(
reply_msg(), channel_handle, plugin_pid, plugin_child_id);
SendReplyAndDeleteThis();
}
virtual bool OffTheRecord() OVERRIDE {
return filter()->OffTheRecord();
}
virtual ResourceContext* GetResourceContext() OVERRIDE {
return context_;
}
private:
ResourceContext* context_;
};
class OpenChannelToPpapiBrokerCallback
: public PpapiPluginProcessHost::BrokerClient {
public:
OpenChannelToPpapiBrokerCallback(RenderMessageFilter* filter,
int routing_id)
: filter_(filter),
routing_id_(routing_id) {
}
virtual ~OpenChannelToPpapiBrokerCallback() {}
virtual void GetPpapiChannelInfo(base::ProcessHandle* renderer_handle,
int* renderer_id) OVERRIDE {
*renderer_handle = filter_->PeerHandle();
*renderer_id = filter_->render_process_id();
}
virtual void OnPpapiChannelOpened(const IPC::ChannelHandle& channel_handle,
base::ProcessId plugin_pid,
int ) OVERRIDE {
filter_->Send(new ViewMsg_PpapiBrokerChannelCreated(routing_id_,
plugin_pid,
channel_handle));
delete this;
}
virtual bool OffTheRecord() OVERRIDE {
return filter_->OffTheRecord();
}
private:
scoped_refptr<RenderMessageFilter> filter_;
int routing_id_;
};
#if defined(OS_MACOSX)
void AddBooleanValue(CFMutableDictionaryRef dictionary,
const CFStringRef key,
bool value) {
CFDictionaryAddValue(
dictionary, key, value ? kCFBooleanTrue : kCFBooleanFalse);
}
void AddIntegerValue(CFMutableDictionaryRef dictionary,
const CFStringRef key,
int32 value) {
base::ScopedCFTypeRef<CFNumberRef> number(
CFNumberCreate(NULL, kCFNumberSInt32Type, &value));
CFDictionaryAddValue(dictionary, key, number.get());
}
#endif
}
class RenderMessageFilter::OpenChannelToNpapiPluginCallback
: public RenderMessageCompletionCallback,
public PluginProcessHost::Client {
public:
OpenChannelToNpapiPluginCallback(RenderMessageFilter* filter,
ResourceContext* context,
IPC::Message* reply_msg)
: RenderMessageCompletionCallback(filter, reply_msg),
context_(context),
host_(NULL),
sent_plugin_channel_request_(false) {
}
virtual int ID() OVERRIDE {
return filter()->render_process_id();
}
virtual ResourceContext* GetResourceContext() OVERRIDE {
return context_;
}
virtual bool OffTheRecord() OVERRIDE {
if (filter()->OffTheRecord())
return true;
if (GetContentClient()->browser()->AllowSaveLocalState(context_))
return false;
for (size_t i = 0; i < info_.mime_types.size(); ++i) {
if (info_.mime_types[i].mime_type == kFlashPluginSwfMimeType)
return true;
}
return false;
}
virtual void SetPluginInfo(const WebPluginInfo& info) OVERRIDE {
info_ = info;
}
virtual void OnFoundPluginProcessHost(PluginProcessHost* host) OVERRIDE {
DCHECK(host);
host_ = host;
}
virtual void OnSentPluginChannelRequest() OVERRIDE {
sent_plugin_channel_request_ = true;
}
virtual void OnChannelOpened(const IPC::ChannelHandle& handle) OVERRIDE {
WriteReplyAndDeleteThis(handle);
}
virtual void OnError() OVERRIDE {
WriteReplyAndDeleteThis(IPC::ChannelHandle());
}
PluginProcessHost* host() const {
return host_;
}
bool sent_plugin_channel_request() const {
return sent_plugin_channel_request_;
}
void Cancel() {
delete this;
}
private:
void WriteReplyAndDeleteThis(const IPC::ChannelHandle& handle) {
FrameHostMsg_OpenChannelToPlugin::WriteReplyParams(reply_msg(),
handle, info_);
filter()->OnCompletedOpenChannelToNpapiPlugin(this);
SendReplyAndDeleteThis();
}
ResourceContext* context_;
WebPluginInfo info_;
PluginProcessHost* host_;
bool sent_plugin_channel_request_;
};
RenderMessageFilter::RenderMessageFilter(
int render_process_id,
bool is_guest,
PluginServiceImpl* plugin_service,
BrowserContext* browser_context,
net::URLRequestContextGetter* request_context,
RenderWidgetHelper* render_widget_helper,
media::AudioManager* audio_manager,
MediaInternals* media_internals,
DOMStorageContextWrapper* dom_storage_context)
: BrowserMessageFilter(
kFilteredMessageClasses, arraysize(kFilteredMessageClasses)),
resource_dispatcher_host_(ResourceDispatcherHostImpl::Get()),
plugin_service_(plugin_service),
profile_data_directory_(browser_context->GetPath()),
request_context_(request_context),
resource_context_(browser_context->GetResourceContext()),
render_widget_helper_(render_widget_helper),
incognito_(browser_context->IsOffTheRecord()),
dom_storage_context_(dom_storage_context),
render_process_id_(render_process_id),
is_guest_(is_guest),
cpu_usage_(0),
audio_manager_(audio_manager),
media_internals_(media_internals) {
DCHECK(request_context_.get());
render_widget_helper_->Init(render_process_id_, resource_dispatcher_host_);
}
RenderMessageFilter::~RenderMessageFilter() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(plugin_host_clients_.empty());
}
void RenderMessageFilter::OnChannelClosing() {
HostSharedBitmapManager::current()->ProcessRemoved(PeerHandle());
#if defined(ENABLE_PLUGINS)
for (std::set<OpenChannelToNpapiPluginCallback*>::iterator it =
plugin_host_clients_.begin(); it != plugin_host_clients_.end(); ++it) {
OpenChannelToNpapiPluginCallback* client = *it;
if (client->host()) {
if (client->sent_plugin_channel_request()) {
client->host()->CancelSentRequest(client);
} else {
client->host()->CancelPendingRequest(client);
}
} else {
plugin_service_->CancelOpenChannelToNpapiPlugin(client);
}
client->Cancel();
}
#endif
plugin_host_clients_.clear();
#if defined(OS_ANDROID)
CompositorImpl::DestroyAllSurfaceTextures(render_process_id_);
#endif
}
void RenderMessageFilter::OnChannelConnected(int32 peer_id) {
base::ProcessHandle handle = PeerHandle();
#if defined(OS_MACOSX)
process_metrics_.reset(base::ProcessMetrics::CreateProcessMetrics(handle,
NULL));
#else
process_metrics_.reset(base::ProcessMetrics::CreateProcessMetrics(handle));
#endif
cpu_usage_ = process_metrics_->GetCPUUsage();
cpu_usage_sample_time_ = base::TimeTicks::Now();
}
bool RenderMessageFilter::OnMessageReceived(const IPC::Message& message,
bool* message_was_ok) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP_EX(RenderMessageFilter, message, *message_was_ok)
#if defined(OS_WIN)
IPC_MESSAGE_HANDLER(ViewHostMsg_PreCacheFontCharacters,
OnPreCacheFontCharacters)
#endif
IPC_MESSAGE_HANDLER(ViewHostMsg_GetProcessMemorySizes,
OnGetProcessMemorySizes)
IPC_MESSAGE_HANDLER(ViewHostMsg_GenerateRoutingID, OnGenerateRoutingID)
IPC_MESSAGE_HANDLER(ViewHostMsg_CreateWindow, OnCreateWindow)
IPC_MESSAGE_HANDLER(ViewHostMsg_CreateWidget, OnCreateWidget)
IPC_MESSAGE_HANDLER(ViewHostMsg_CreateFullscreenWidget,
OnCreateFullscreenWidget)
IPC_MESSAGE_HANDLER(ViewHostMsg_SetCookie, OnSetCookie)
IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_GetCookies, OnGetCookies)
IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_GetRawCookies, OnGetRawCookies)
IPC_MESSAGE_HANDLER(ViewHostMsg_DeleteCookie, OnDeleteCookie)
IPC_MESSAGE_HANDLER(ViewHostMsg_CookiesEnabled, OnCookiesEnabled)
#if defined(OS_MACOSX)
IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_LoadFont, OnLoadFont)
#endif
IPC_MESSAGE_HANDLER(ViewHostMsg_DownloadUrl, OnDownloadUrl)
#if defined(ENABLE_PLUGINS)
IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_GetPlugins, OnGetPlugins)
IPC_MESSAGE_HANDLER(FrameHostMsg_GetPluginInfo, OnGetPluginInfo)
IPC_MESSAGE_HANDLER_DELAY_REPLY(FrameHostMsg_OpenChannelToPlugin,
OnOpenChannelToPlugin)
IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_OpenChannelToPepperPlugin,
OnOpenChannelToPepperPlugin)
IPC_MESSAGE_HANDLER(ViewHostMsg_DidCreateOutOfProcessPepperInstance,
OnDidCreateOutOfProcessPepperInstance)
IPC_MESSAGE_HANDLER(ViewHostMsg_DidDeleteOutOfProcessPepperInstance,
OnDidDeleteOutOfProcessPepperInstance)
IPC_MESSAGE_HANDLER(ViewHostMsg_OpenChannelToPpapiBroker,
OnOpenChannelToPpapiBroker)
#endif
IPC_MESSAGE_HANDLER_GENERIC(ViewHostMsg_UpdateRect,
render_widget_helper_->DidReceiveBackingStoreMsg(message))
IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateIsDelayed, OnUpdateIsDelayed)
IPC_MESSAGE_HANDLER(DesktopNotificationHostMsg_CheckPermission,
OnCheckNotificationPermission)
IPC_MESSAGE_HANDLER(ChildProcessHostMsg_SyncAllocateSharedMemory,
OnAllocateSharedMemory)
IPC_MESSAGE_HANDLER(ChildProcessHostMsg_SyncAllocateSharedBitmap,
OnAllocateSharedBitmap)
IPC_MESSAGE_HANDLER(ChildProcessHostMsg_SyncAllocateGpuMemoryBuffer,
OnAllocateGpuMemoryBuffer)
IPC_MESSAGE_HANDLER(ChildProcessHostMsg_AllocatedSharedBitmap,
OnAllocatedSharedBitmap)
IPC_MESSAGE_HANDLER(ChildProcessHostMsg_DeletedSharedBitmap,
OnDeletedSharedBitmap)
#if defined(OS_POSIX) && !defined(TOOLKIT_GTK) && !defined(OS_ANDROID)
IPC_MESSAGE_HANDLER(ViewHostMsg_AllocTransportDIB, OnAllocTransportDIB)
IPC_MESSAGE_HANDLER(ViewHostMsg_FreeTransportDIB, OnFreeTransportDIB)
#endif
IPC_MESSAGE_HANDLER(ViewHostMsg_DidGenerateCacheableMetadata,
OnCacheableMetadataAvailable)
IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_Keygen, OnKeygen)
IPC_MESSAGE_HANDLER(ViewHostMsg_GetCPUUsage, OnGetCPUUsage)
IPC_MESSAGE_HANDLER(ViewHostMsg_GetAudioHardwareConfig,
OnGetAudioHardwareConfig)
#if defined(OS_WIN)
IPC_MESSAGE_HANDLER(ViewHostMsg_GetMonitorColorProfile,
OnGetMonitorColorProfile)
#endif
IPC_MESSAGE_HANDLER(ViewHostMsg_MediaLogEvents, OnMediaLogEvents)
IPC_MESSAGE_HANDLER(ViewHostMsg_Are3DAPIsBlocked, OnAre3DAPIsBlocked)
IPC_MESSAGE_HANDLER(ViewHostMsg_DidLose3DContext, OnDidLose3DContext)
#if defined(OS_ANDROID)
IPC_MESSAGE_HANDLER(ViewHostMsg_RunWebAudioMediaCodec, OnWebAudioMediaCodec)
#endif
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP_EX()
return handled;
}
void RenderMessageFilter::OnDestruct() const {
BrowserThread::DeleteOnIOThread::Destruct(this);
}
base::TaskRunner* RenderMessageFilter::OverrideTaskRunnerForMessage(
const IPC::Message& message) {
#if defined(OS_WIN)
if (message.type() == ViewHostMsg_GetMonitorColorProfile::ID)
return BrowserThread::GetBlockingPool();
#endif
if (message.type() == ViewHostMsg_GetAudioHardwareConfig::ID)
return audio_manager_->GetTaskRunner().get();
return NULL;
}
bool RenderMessageFilter::OffTheRecord() const {
return incognito_;
}
void RenderMessageFilter::OnCreateWindow(
const ViewHostMsg_CreateWindow_Params& params,
int* route_id,
int* main_frame_route_id,
int* surface_id,
int64* cloned_session_storage_namespace_id) {
bool no_javascript_access;
blink::WebVector<blink::WebString> additional_features(
params.additional_features.size());
for (size_t i = 0; i < params.additional_features.size(); ++i)
additional_features[i] = blink::WebString(params.additional_features[i]);
blink::WebWindowFeatures features = params.features;
features.additionalFeatures.swap(additional_features);
bool can_create_window =
GetContentClient()->browser()->CanCreateWindow(
params.opener_url,
params.opener_top_level_frame_url,
params.opener_security_origin,
params.window_container_type,
params.target_url,
params.referrer,
params.disposition,
features,
params.user_gesture,
params.opener_suppressed,
resource_context_,
render_process_id_,
is_guest_,
params.opener_id,
&no_javascript_access);
if (!can_create_window) {
*route_id = MSG_ROUTING_NONE;
*main_frame_route_id = MSG_ROUTING_NONE;
*surface_id = 0;
return;
}
scoped_refptr<SessionStorageNamespaceImpl> cloned_namespace =
new SessionStorageNamespaceImpl(dom_storage_context_.get(),
params.session_storage_namespace_id);
*cloned_session_storage_namespace_id = cloned_namespace->id();
render_widget_helper_->CreateNewWindow(params,
no_javascript_access,
PeerHandle(),
route_id,
main_frame_route_id,
surface_id,
cloned_namespace.get());
}
void RenderMessageFilter::OnCreateWidget(int opener_id,
blink::WebPopupType popup_type,
int* route_id,
int* surface_id) {
render_widget_helper_->CreateNewWidget(
opener_id, popup_type, route_id, surface_id);
}
void RenderMessageFilter::OnCreateFullscreenWidget(int opener_id,
int* route_id,
int* surface_id) {
render_widget_helper_->CreateNewFullscreenWidget(
opener_id, route_id, surface_id);
}
void RenderMessageFilter::OnGetProcessMemorySizes(size_t* private_bytes,
size_t* shared_bytes) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
using base::ProcessMetrics;
#if !defined(OS_MACOSX) || defined(OS_IOS)
scoped_ptr<ProcessMetrics> metrics(ProcessMetrics::CreateProcessMetrics(
PeerHandle()));
#else
scoped_ptr<ProcessMetrics> metrics(ProcessMetrics::CreateProcessMetrics(
PeerHandle(), content::BrowserChildProcessHost::GetPortProvider()));
#endif
if (!metrics->GetMemoryBytes(private_bytes, shared_bytes)) {
*private_bytes = 0;
*shared_bytes = 0;
}
}
void RenderMessageFilter::OnSetCookie(int render_frame_id,
const GURL& url,
const GURL& first_party_for_cookies,
const std::string& cookie) {
ChildProcessSecurityPolicyImpl* policy =
ChildProcessSecurityPolicyImpl::GetInstance();
if (!policy->CanAccessCookiesForOrigin(render_process_id_, url))
return;
net::CookieOptions options;
if (GetContentClient()->browser()->AllowSetCookie(
url, first_party_for_cookies, cookie, resource_context_,
render_process_id_, render_frame_id, &options)) {
net::CookieStore* cookie_store = GetCookieStoreForURL(url);
cookie_store->SetCookieWithOptionsAsync(
url, cookie, options, net::CookieStore::SetCookiesCallback());
}
}
void RenderMessageFilter::OnGetCookies(int render_frame_id,
const GURL& url,
const GURL& first_party_for_cookies,
IPC::Message* reply_msg) {
ChildProcessSecurityPolicyImpl* policy =
ChildProcessSecurityPolicyImpl::GetInstance();
if (!policy->CanAccessCookiesForOrigin(render_process_id_, url)) {
SendGetCookiesResponse(reply_msg, std::string());
return;
}
char url_buf[128];
base::strlcpy(url_buf, url.spec().c_str(), arraysize(url_buf));
base::debug::Alias(url_buf);
net::CookieStore* cookie_store = GetCookieStoreForURL(url);
cookie_store->GetAllCookiesForURLAsync(
url, base::Bind(&RenderMessageFilter::CheckPolicyForCookies, this,
render_frame_id, url, first_party_for_cookies,
reply_msg));
}
void RenderMessageFilter::OnGetRawCookies(
const GURL& url,
const GURL& first_party_for_cookies,
IPC::Message* reply_msg) {
ChildProcessSecurityPolicyImpl* policy =
ChildProcessSecurityPolicyImpl::GetInstance();
if (!policy->CanReadRawCookies(render_process_id_) ||
!policy->CanAccessCookiesForOrigin(render_process_id_, url)) {
SendGetRawCookiesResponse(reply_msg, net::CookieList());
return;
}
net::CookieStore* cookie_store = GetCookieStoreForURL(url);
cookie_store->GetAllCookiesForURLAsync(
url, base::Bind(&RenderMessageFilter::SendGetRawCookiesResponse,
this, reply_msg));
}
void RenderMessageFilter::OnDeleteCookie(const GURL& url,
const std::string& cookie_name) {
ChildProcessSecurityPolicyImpl* policy =
ChildProcessSecurityPolicyImpl::GetInstance();
if (!policy->CanAccessCookiesForOrigin(render_process_id_, url))
return;
net::CookieStore* cookie_store = GetCookieStoreForURL(url);
cookie_store->DeleteCookieAsync(url, cookie_name, base::Closure());
}
void RenderMessageFilter::OnCookiesEnabled(
const GURL& url,
const GURL& first_party_for_cookies,
bool* cookies_enabled) {
*cookies_enabled = GetContentClient()->browser()->AllowGetCookie(
url, first_party_for_cookies, net::CookieList(), resource_context_,
render_process_id_, MSG_ROUTING_CONTROL);
}
#if defined(OS_MACOSX)
void RenderMessageFilter::OnLoadFont(const FontDescriptor& font,
IPC::Message* reply_msg) {
FontLoader::Result* result = new FontLoader::Result;
BrowserThread::PostTaskAndReply(
BrowserThread::FILE, FROM_HERE,
base::Bind(&FontLoader::LoadFont, font, result),
base::Bind(&RenderMessageFilter::SendLoadFontReply, this, reply_msg,
base::Owned(result)));
}
void RenderMessageFilter::SendLoadFontReply(IPC::Message* reply,
FontLoader::Result* result) {
base::SharedMemoryHandle handle;
if (result->font_data_size == 0 || result->font_id == 0) {
result->font_data_size = 0;
result->font_id = 0;
handle = base::SharedMemory::NULLHandle();
} else {
result->font_data.GiveToProcess(base::GetCurrentProcessHandle(), &handle);
}
ViewHostMsg_LoadFont::WriteReplyParams(
reply, result->font_data_size, handle, result->font_id);
Send(reply);
}
#endif
#if defined(ENABLE_PLUGINS)
void RenderMessageFilter::OnGetPlugins(
bool refresh,
IPC::Message* reply_msg) {
if (refresh) {
const base::TimeDelta threshold = base::TimeDelta::FromSeconds(
kPluginsRefreshThresholdInSeconds);
const base::TimeTicks now = base::TimeTicks::Now();
if (now - last_plugin_refresh_time_ >= threshold) {
PluginServiceImpl::GetInstance()->RefreshPlugins();
last_plugin_refresh_time_ = now;
}
}
PluginServiceImpl::GetInstance()->GetPlugins(
base::Bind(&RenderMessageFilter::GetPluginsCallback, this, reply_msg));
}
void RenderMessageFilter::GetPluginsCallback(
IPC::Message* reply_msg,
const std::vector<WebPluginInfo>& all_plugins) {
PluginServiceFilter* filter = PluginServiceImpl::GetInstance()->GetFilter();
std::vector<WebPluginInfo> plugins;
int child_process_id = -1;
int routing_id = MSG_ROUTING_NONE;
for (size_t i = 0; i < all_plugins.size(); ++i) {
WebPluginInfo plugin(all_plugins[i]);
if (!filter || filter->IsPluginAvailable(child_process_id,
routing_id,
resource_context_,
GURL(),
GURL(),
&plugin)) {
plugins.push_back(plugin);
}
}
ViewHostMsg_GetPlugins::WriteReplyParams(reply_msg, plugins);
Send(reply_msg);
}
void RenderMessageFilter::OnGetPluginInfo(
int render_frame_id,
const GURL& url,
const GURL& page_url,
const std::string& mime_type,
bool* found,
WebPluginInfo* info,
std::string* actual_mime_type) {
bool allow_wildcard = true;
*found = plugin_service_->GetPluginInfo(
render_process_id_, render_frame_id, resource_context_,
url, page_url, mime_type, allow_wildcard,
NULL, info, actual_mime_type);
}
void RenderMessageFilter::OnOpenChannelToPlugin(int render_frame_id,
const GURL& url,
const GURL& policy_url,
const std::string& mime_type,
IPC::Message* reply_msg) {
OpenChannelToNpapiPluginCallback* client =
new OpenChannelToNpapiPluginCallback(this, resource_context_, reply_msg);
DCHECK(!ContainsKey(plugin_host_clients_, client));
plugin_host_clients_.insert(client);
plugin_service_->OpenChannelToNpapiPlugin(
render_process_id_, render_frame_id,
url, policy_url, mime_type, client);
}
void RenderMessageFilter::OnOpenChannelToPepperPlugin(
const base::FilePath& path,
IPC::Message* reply_msg) {
plugin_service_->OpenChannelToPpapiPlugin(
render_process_id_,
path,
profile_data_directory_,
new OpenChannelToPpapiPluginCallback(this, resource_context_, reply_msg));
}
void RenderMessageFilter::OnDidCreateOutOfProcessPepperInstance(
int plugin_child_id,
int32 pp_instance,
PepperRendererInstanceData instance_data,
bool is_external) {
DCHECK_EQ(0, instance_data.render_process_id);
instance_data.render_process_id = render_process_id_;
if (is_external) {
BrowserPpapiHostImpl* host = static_cast<BrowserPpapiHostImpl*>(
GetContentClient()->browser()->GetExternalBrowserPpapiHost(
plugin_child_id));
if (host)
host->AddInstance(pp_instance, instance_data);
} else {
PpapiPluginProcessHost::DidCreateOutOfProcessInstance(
plugin_child_id, pp_instance, instance_data);
}
}
void RenderMessageFilter::OnDidDeleteOutOfProcessPepperInstance(
int plugin_child_id,
int32 pp_instance,
bool is_external) {
if (is_external) {
BrowserPpapiHostImpl* host = static_cast<BrowserPpapiHostImpl*>(
GetContentClient()->browser()->GetExternalBrowserPpapiHost(
plugin_child_id));
if (host)
host->DeleteInstance(pp_instance);
} else {
PpapiPluginProcessHost::DidDeleteOutOfProcessInstance(
plugin_child_id, pp_instance);
}
}
void RenderMessageFilter::OnOpenChannelToPpapiBroker(
int routing_id,
const base::FilePath& path) {
plugin_service_->OpenChannelToPpapiBroker(
render_process_id_,
path,
new OpenChannelToPpapiBrokerCallback(this, routing_id));
}
#endif
void RenderMessageFilter::OnGenerateRoutingID(int* route_id) {
*route_id = render_widget_helper_->GetNextRoutingID();
}
void RenderMessageFilter::OnGetCPUUsage(int* cpu_usage) {
base::TimeTicks now = base::TimeTicks::Now();
int64 since_last_sample_ms = (now - cpu_usage_sample_time_).InMilliseconds();
if (since_last_sample_ms > kCPUUsageSampleIntervalMs) {
cpu_usage_sample_time_ = now;
cpu_usage_ = static_cast<int>(process_metrics_->GetCPUUsage());
}
*cpu_usage = cpu_usage_;
}
void RenderMessageFilter::OnGetAudioHardwareConfig(
media::AudioParameters* input_params,
media::AudioParameters* output_params) {
DCHECK(input_params);
DCHECK(output_params);
*output_params = audio_manager_->GetDefaultOutputStreamParameters();
*input_params = audio_manager_->GetInputStreamParameters(
media::AudioManagerBase::kDefaultDeviceId);
}
#if defined(OS_WIN)
void RenderMessageFilter::OnGetMonitorColorProfile(std::vector<char>* profile) {
DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO));
static bool enabled = false;
static bool checked = false;
if (!checked) {
checked = true;
const CommandLine& command = *CommandLine::ForCurrentProcess();
enabled = command.HasSwitch(switches::kEnableMonitorProfile);
}
if (enabled)
return;
*profile = g_color_profile.Get().profile();
}
#endif
void RenderMessageFilter::OnDownloadUrl(const IPC::Message& message,
const GURL& url,
const Referrer& referrer,
const base::string16& suggested_name) {
scoped_ptr<DownloadSaveInfo> save_info(new DownloadSaveInfo());
save_info->suggested_name = suggested_name;
scoped_ptr<net::URLRequest> request(
resource_context_->GetRequestContext()->CreateRequest(
url, net::DEFAULT_PRIORITY, NULL, NULL));
RecordDownloadSource(INITIATED_BY_RENDERER);
resource_dispatcher_host_->BeginDownload(
request.Pass(),
referrer,
true,
resource_context_,
render_process_id_,
message.routing_id(),
false,
save_info.Pass(),
content::DownloadItem::kInvalidId,
ResourceDispatcherHostImpl::DownloadStartedCallback());
}
void RenderMessageFilter::OnCheckNotificationPermission(
const GURL& source_origin, int* result) {
#if defined(ENABLE_NOTIFICATIONS)
*result = GetContentClient()->browser()->
CheckDesktopNotificationPermission(source_origin, resource_context_,
render_process_id_);
#else
*result = blink::WebNotificationPresenter::PermissionAllowed;
#endif
}
void RenderMessageFilter::OnAllocateSharedMemory(
uint32 buffer_size,
base::SharedMemoryHandle* handle) {
ChildProcessHostImpl::AllocateSharedMemory(
buffer_size, PeerHandle(), handle);
}
void RenderMessageFilter::OnAllocateSharedBitmap(
uint32 buffer_size,
const cc::SharedBitmapId& id,
base::SharedMemoryHandle* handle) {
HostSharedBitmapManager::current()->AllocateSharedBitmapForChild(
PeerHandle(), buffer_size, id, handle);
}
void RenderMessageFilter::OnAllocatedSharedBitmap(
size_t buffer_size,
const base::SharedMemoryHandle& handle,
const cc::SharedBitmapId& id) {
HostSharedBitmapManager::current()->ChildAllocatedSharedBitmap(
buffer_size, handle, PeerHandle(), id);
}
void RenderMessageFilter::OnDeletedSharedBitmap(const cc::SharedBitmapId& id) {
HostSharedBitmapManager::current()->ChildDeletedSharedBitmap(id);
}
net::CookieStore* RenderMessageFilter::GetCookieStoreForURL(
const GURL& url) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
net::URLRequestContext* context =
GetContentClient()->browser()->OverrideRequestContextForURL(
url, resource_context_);
if (context)
return context->cookie_store();
net::CookieStore* cookie_store =
GetContentClient()->browser()->OverrideCookieStoreForRenderProcess(
render_process_id_);
if (cookie_store)
return cookie_store;
return request_context_->GetURLRequestContext()->cookie_store();
}
#if defined(OS_POSIX) && !defined(TOOLKIT_GTK) && !defined(OS_ANDROID)
void RenderMessageFilter::OnAllocTransportDIB(
uint32 size, bool cache_in_browser, TransportDIB::Handle* handle) {
render_widget_helper_->AllocTransportDIB(size, cache_in_browser, handle);
}
void RenderMessageFilter::OnFreeTransportDIB(
TransportDIB::Id dib_id) {
render_widget_helper_->FreeTransportDIB(dib_id);
}
#endif
bool RenderMessageFilter::CheckPreparsedJsCachingEnabled() const {
static bool checked = false;
static bool result = false;
if (!checked) {
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
result = command_line.HasSwitch(switches::kEnablePreparsedJsCaching);
checked = true;
}
return result;
}
void RenderMessageFilter::OnCacheableMetadataAvailable(
const GURL& url,
double expected_response_time,
const std::vector<char>& data) {
if (!CheckPreparsedJsCachingEnabled())
return;
net::HttpCache* cache = request_context_->GetURLRequestContext()->
http_transaction_factory()->GetCache();
DCHECK(cache);
const net::RequestPriority kPriority = net::LOW;
scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(data.size()));
memcpy(buf->data(), &data.front(), data.size());
cache->WriteMetadata(url,
kPriority,
base::Time::FromDoubleT(expected_response_time),
buf.get(),
data.size());
}
void RenderMessageFilter::OnKeygen(uint32 key_size_index,
const std::string& challenge_string,
const GURL& url,
IPC::Message* reply_msg) {
int key_size_in_bits;
switch (key_size_index) {
case 0:
key_size_in_bits = 2048;
break;
case 1:
key_size_in_bits = 1024;
break;
default:
DCHECK(false) << "Illegal key_size_index " << key_size_index;
ViewHostMsg_Keygen::WriteReplyParams(reply_msg, std::string());
Send(reply_msg);
return;
}
resource_context_->CreateKeygenHandler(
key_size_in_bits,
challenge_string,
url,
base::Bind(
&RenderMessageFilter::PostKeygenToWorkerThread, this, reply_msg));
}
void RenderMessageFilter::PostKeygenToWorkerThread(
IPC::Message* reply_msg,
scoped_ptr<net::KeygenHandler> keygen_handler) {
VLOG(1) << "Dispatching keygen task to worker pool.";
if (!base::WorkerPool::PostTask(
FROM_HERE,
base::Bind(&RenderMessageFilter::OnKeygenOnWorkerThread,
this,
base::Passed(&keygen_handler),
reply_msg),
true)) {
NOTREACHED() << "Failed to dispatch keygen task to worker pool";
ViewHostMsg_Keygen::WriteReplyParams(reply_msg, std::string());
Send(reply_msg);
}
}
void RenderMessageFilter::OnKeygenOnWorkerThread(
scoped_ptr<net::KeygenHandler> keygen_handler,
IPC::Message* reply_msg) {
DCHECK(reply_msg);
ViewHostMsg_Keygen::WriteReplyParams(
reply_msg,
keygen_handler->GenKeyAndSignChallenge());
Send(reply_msg);
}
void RenderMessageFilter::OnMediaLogEvents(
const std::vector<media::MediaLogEvent>& events) {
if (media_internals_)
media_internals_->OnMediaEvents(render_process_id_, events);
}
void RenderMessageFilter::CheckPolicyForCookies(
int render_frame_id,
const GURL& url,
const GURL& first_party_for_cookies,
IPC::Message* reply_msg,
const net::CookieList& cookie_list) {
net::CookieStore* cookie_store = GetCookieStoreForURL(url);
if (GetContentClient()->browser()->AllowGetCookie(
url, first_party_for_cookies, cookie_list, resource_context_,
render_process_id_, render_frame_id)) {
cookie_store->GetCookiesWithOptionsAsync(
url, net::CookieOptions(),
base::Bind(&RenderMessageFilter::SendGetCookiesResponse,
this, reply_msg));
} else {
SendGetCookiesResponse(reply_msg, std::string());
}
}
void RenderMessageFilter::SendGetCookiesResponse(IPC::Message* reply_msg,
const std::string& cookies) {
ViewHostMsg_GetCookies::WriteReplyParams(reply_msg, cookies);
Send(reply_msg);
}
void RenderMessageFilter::SendGetRawCookiesResponse(
IPC::Message* reply_msg,
const net::CookieList& cookie_list) {
std::vector<CookieData> cookies;
for (size_t i = 0; i < cookie_list.size(); ++i)
cookies.push_back(CookieData(cookie_list[i]));
ViewHostMsg_GetRawCookies::WriteReplyParams(reply_msg, cookies);
Send(reply_msg);
}
void RenderMessageFilter::OnCompletedOpenChannelToNpapiPlugin(
OpenChannelToNpapiPluginCallback* client) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(ContainsKey(plugin_host_clients_, client));
plugin_host_clients_.erase(client);
}
void RenderMessageFilter::OnUpdateIsDelayed(const IPC::Message& msg) {
render_widget_helper_->DidReceiveBackingStoreMsg(msg);
}
void RenderMessageFilter::OnAre3DAPIsBlocked(int render_view_id,
const GURL& top_origin_url,
ThreeDAPIType requester,
bool* blocked) {
*blocked = GpuDataManagerImpl::GetInstance()->Are3DAPIsBlocked(
top_origin_url, render_process_id_, render_view_id, requester);
}
void RenderMessageFilter::OnDidLose3DContext(
const GURL& top_origin_url,
ThreeDAPIType ,
int arb_robustness_status_code) {
#if defined(OS_MACOSX)
#ifndef GL_GUILTY_CONTEXT_RESET_ARB
#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253
#endif
#ifndef GL_INNOCENT_CONTEXT_RESET_ARB
#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254
#endif
#ifndef GL_UNKNOWN_CONTEXT_RESET_ARB
#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255
#endif
#endif
GpuDataManagerImpl::DomainGuilt guilt;
switch (arb_robustness_status_code) {
case GL_GUILTY_CONTEXT_RESET_ARB:
guilt = GpuDataManagerImpl::DOMAIN_GUILT_KNOWN;
break;
case GL_UNKNOWN_CONTEXT_RESET_ARB:
guilt = GpuDataManagerImpl::DOMAIN_GUILT_UNKNOWN;
break;
default:
return;
}
GpuDataManagerImpl::GetInstance()->BlockDomainFrom3DAPIs(
top_origin_url, guilt);
}
#if defined(OS_WIN)
void RenderMessageFilter::OnPreCacheFontCharacters(const LOGFONT& font,
const base::string16& str) {
if (!ShouldUseDirectWrite())
return;
HDC hdc = CreateEnhMetaFile(NULL, NULL, NULL, NULL);
HFONT font_handle = CreateFontIndirect(&font);
DCHECK(NULL != font_handle);
HGDIOBJ old_font = SelectObject(hdc, font_handle);
DCHECK(NULL != old_font);
ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, str.c_str(), str.length(), NULL);
SelectObject(hdc, old_font);
DeleteObject(font_handle);
HENHMETAFILE metafile = CloseEnhMetaFile(hdc);
if (metafile) {
DeleteEnhMetaFile(metafile);
}
}
#endif
#if defined(OS_ANDROID)
void RenderMessageFilter::OnWebAudioMediaCodec(
base::SharedMemoryHandle encoded_data_handle,
base::FileDescriptor pcm_output,
uint32_t data_size) {
base::WorkerPool::PostTask(
FROM_HERE,
base::Bind(&media::WebAudioMediaCodecBridge::RunWebAudioMediaCodec,
encoded_data_handle, pcm_output, data_size),
true);
}
#endif
void RenderMessageFilter::OnAllocateGpuMemoryBuffer(
uint32 width,
uint32 height,
uint32 internalformat,
gfx::GpuMemoryBufferHandle* handle) {
if (!GpuMemoryBufferImpl::IsFormatValid(internalformat)) {
handle->type = gfx::EMPTY_BUFFER;
return;
}
#if defined(OS_MACOSX)
if (GpuMemoryBufferImplIOSurface::IsFormatSupported(internalformat)) {
IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize();
if (io_surface_support) {
base::ScopedCFTypeRef<CFMutableDictionaryRef> properties;
properties.reset(
CFDictionaryCreateMutable(kCFAllocatorDefault,
0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks));
AddIntegerValue(properties,
io_surface_support->GetKIOSurfaceWidth(),
width);
AddIntegerValue(properties,
io_surface_support->GetKIOSurfaceHeight(),
height);
AddIntegerValue(properties,
io_surface_support->GetKIOSurfaceBytesPerElement(),
GpuMemoryBufferImpl::BytesPerPixel(internalformat));
AddIntegerValue(properties,
io_surface_support->GetKIOSurfacePixelFormat(),
GpuMemoryBufferImplIOSurface::PixelFormat(
internalformat));
AddBooleanValue(properties,
io_surface_support->GetKIOSurfaceIsGlobal(),
true);
base::ScopedCFTypeRef<CFTypeRef> io_surface(
io_surface_support->IOSurfaceCreate(properties));
if (io_surface) {
handle->type = gfx::IO_SURFACE_BUFFER;
handle->io_surface_id = io_surface_support->IOSurfaceGetID(io_surface);
last_io_surface_ = io_surface;
return;
}
}
}
#endif
#if defined(OS_ANDROID)
if (GpuMemoryBufferImplSurfaceTexture::IsFormatSupported(internalformat)) {
int surface_texture_id =
CompositorImpl::CreateSurfaceTexture(render_process_id_);
if (surface_texture_id != -1) {
handle->type = gfx::SURFACE_TEXTURE_BUFFER;
handle->surface_texture_id =
gfx::SurfaceTextureId(surface_texture_id, render_process_id_);
return;
}
}
#endif
uint64 stride = static_cast<uint64>(width) *
GpuMemoryBufferImpl::BytesPerPixel(internalformat);
if (stride > std::numeric_limits<uint32>::max()) {
handle->type = gfx::EMPTY_BUFFER;
return;
}
uint64 buffer_size = stride * static_cast<uint64>(height);
if (buffer_size > std::numeric_limits<size_t>::max()) {
handle->type = gfx::EMPTY_BUFFER;
return;
}
handle->type = gfx::SHARED_MEMORY_BUFFER;
ChildProcessHostImpl::AllocateSharedMemory(
static_cast<size_t>(buffer_size), PeerHandle(), &handle->handle);
}
}