1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/renderer_host/render_message_filter.h"
10 #include "base/bind_helpers.h"
11 #include "base/command_line.h"
12 #include "base/debug/alias.h"
13 #include "base/strings/sys_string_conversions.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "base/threading/thread.h"
16 #include "base/threading/worker_pool.h"
17 #include "content/browser/browser_main_loop.h"
18 #include "content/browser/child_process_security_policy_impl.h"
19 #include "content/browser/dom_storage/dom_storage_context_wrapper.h"
20 #include "content/browser/dom_storage/session_storage_namespace_impl.h"
21 #include "content/browser/download/download_stats.h"
22 #include "content/browser/gpu/gpu_data_manager_impl.h"
23 #include "content/browser/loader/resource_dispatcher_host_impl.h"
24 #include "content/browser/media/media_internals.h"
25 #include "content/browser/plugin_process_host.h"
26 #include "content/browser/plugin_service_impl.h"
27 #include "content/browser/ppapi_plugin_process_host.h"
28 #include "content/browser/renderer_host/pepper/pepper_security_helper.h"
29 #include "content/browser/renderer_host/render_process_host_impl.h"
30 #include "content/browser/renderer_host/render_view_host_delegate.h"
31 #include "content/browser/renderer_host/render_widget_helper.h"
32 #include "content/browser/renderer_host/render_widget_resize_helper.h"
33 #include "content/browser/transition_request_manager.h"
34 #include "content/common/child_process_host_impl.h"
35 #include "content/common/child_process_messages.h"
36 #include "content/common/cookie_data.h"
37 #include "content/common/desktop_notification_messages.h"
38 #include "content/common/frame_messages.h"
39 #include "content/common/host_shared_bitmap_manager.h"
40 #include "content/common/media/media_param_traits.h"
41 #include "content/common/view_messages.h"
42 #include "content/public/browser/browser_child_process_host.h"
43 #include "content/public/browser/browser_context.h"
44 #include "content/public/browser/browser_thread.h"
45 #include "content/public/browser/content_browser_client.h"
46 #include "content/public/browser/download_save_info.h"
47 #include "content/public/browser/plugin_service_filter.h"
48 #include "content/public/browser/resource_context.h"
49 #include "content/public/browser/user_metrics.h"
50 #include "content/public/common/content_constants.h"
51 #include "content/public/common/content_switches.h"
52 #include "content/public/common/context_menu_params.h"
53 #include "content/public/common/url_constants.h"
54 #include "content/public/common/webplugininfo.h"
55 #include "ipc/ipc_channel_handle.h"
56 #include "ipc/ipc_platform_file.h"
57 #include "media/audio/audio_manager.h"
58 #include "media/audio/audio_manager_base.h"
59 #include "media/audio/audio_parameters.h"
60 #include "media/base/media_log_event.h"
61 #include "net/base/io_buffer.h"
62 #include "net/base/keygen_handler.h"
63 #include "net/base/mime_util.h"
64 #include "net/base/request_priority.h"
65 #include "net/cookies/canonical_cookie.h"
66 #include "net/cookies/cookie_store.h"
67 #include "net/http/http_cache.h"
68 #include "net/url_request/url_request_context.h"
69 #include "net/url_request/url_request_context_getter.h"
70 #include "ppapi/shared_impl/file_type_conversion.h"
71 #include "third_party/WebKit/public/web/WebNotificationPresenter.h"
72 #include "ui/gfx/color_profile.h"
74 #if defined(OS_MACOSX)
75 #include "content/common/mac/font_descriptor.h"
77 #include "gpu/GLES2/gl2extchromium.h"
78 #include "third_party/khronos/GLES2/gl2.h"
79 #include "third_party/khronos/GLES2/gl2ext.h"
82 #include "base/file_descriptor_posix.h"
85 #include "content/common/font_cache_dispatcher_win.h"
86 #include "content/common/sandbox_win.h"
88 #if defined(OS_ANDROID)
89 #include "media/base/android/webaudio_media_codec_bridge.h"
92 using net::CookieStore;
97 #if defined(ENABLE_PLUGINS)
98 const int kPluginsRefreshThresholdInSeconds = 3;
101 // When two CPU usage queries arrive within this interval, we sample the CPU
102 // usage only once and send it as a response for both queries.
103 static const int64 kCPUUsageSampleIntervalMs = 900;
105 const uint32 kFilteredMessageClasses[] = {
106 ChildProcessMsgStart,
107 DesktopNotificationMsgStart,
113 // On Windows, |g_color_profile| can run on an arbitrary background thread.
114 // We avoid races by using LazyInstance's constructor lock to initialize the
116 base::LazyInstance<gfx::ColorProfile>::Leaky g_color_profile =
117 LAZY_INSTANCE_INITIALIZER;
120 // Common functionality for converting a sync renderer message to a callback
121 // function in the browser. Derive from this, create it on the heap when
122 // issuing your callback. When done, write your reply parameters into
123 // reply_msg(), and then call SendReplyAndDeleteThis().
124 class RenderMessageCompletionCallback {
126 RenderMessageCompletionCallback(RenderMessageFilter* filter,
127 IPC::Message* reply_msg)
129 reply_msg_(reply_msg) {
132 virtual ~RenderMessageCompletionCallback() {
135 RenderMessageFilter* filter() { return filter_.get(); }
136 IPC::Message* reply_msg() { return reply_msg_; }
138 void SendReplyAndDeleteThis() {
139 filter_->Send(reply_msg_);
144 scoped_refptr<RenderMessageFilter> filter_;
145 IPC::Message* reply_msg_;
148 class OpenChannelToPpapiPluginCallback
149 : public RenderMessageCompletionCallback,
150 public PpapiPluginProcessHost::PluginClient {
152 OpenChannelToPpapiPluginCallback(RenderMessageFilter* filter,
153 ResourceContext* context,
154 IPC::Message* reply_msg)
155 : RenderMessageCompletionCallback(filter, reply_msg),
159 virtual void GetPpapiChannelInfo(base::ProcessHandle* renderer_handle,
160 int* renderer_id) OVERRIDE {
161 *renderer_handle = filter()->PeerHandle();
162 *renderer_id = filter()->render_process_id();
165 virtual void OnPpapiChannelOpened(const IPC::ChannelHandle& channel_handle,
166 base::ProcessId plugin_pid,
167 int plugin_child_id) OVERRIDE {
168 ViewHostMsg_OpenChannelToPepperPlugin::WriteReplyParams(
169 reply_msg(), channel_handle, plugin_pid, plugin_child_id);
170 SendReplyAndDeleteThis();
173 virtual bool OffTheRecord() OVERRIDE {
174 return filter()->OffTheRecord();
177 virtual ResourceContext* GetResourceContext() OVERRIDE {
182 ResourceContext* context_;
185 class OpenChannelToPpapiBrokerCallback
186 : public PpapiPluginProcessHost::BrokerClient {
188 OpenChannelToPpapiBrokerCallback(RenderMessageFilter* filter,
191 routing_id_(routing_id) {
194 virtual ~OpenChannelToPpapiBrokerCallback() {}
196 virtual void GetPpapiChannelInfo(base::ProcessHandle* renderer_handle,
197 int* renderer_id) OVERRIDE {
198 *renderer_handle = filter_->PeerHandle();
199 *renderer_id = filter_->render_process_id();
202 virtual void OnPpapiChannelOpened(const IPC::ChannelHandle& channel_handle,
203 base::ProcessId plugin_pid,
204 int /* plugin_child_id */) OVERRIDE {
205 filter_->Send(new ViewMsg_PpapiBrokerChannelCreated(routing_id_,
211 virtual bool OffTheRecord() OVERRIDE {
212 return filter_->OffTheRecord();
216 scoped_refptr<RenderMessageFilter> filter_;
222 class RenderMessageFilter::OpenChannelToNpapiPluginCallback
223 : public RenderMessageCompletionCallback,
224 public PluginProcessHost::Client {
226 OpenChannelToNpapiPluginCallback(RenderMessageFilter* filter,
227 ResourceContext* context,
228 IPC::Message* reply_msg)
229 : RenderMessageCompletionCallback(filter, reply_msg),
232 sent_plugin_channel_request_(false) {
235 virtual int ID() OVERRIDE {
236 return filter()->render_process_id();
239 virtual ResourceContext* GetResourceContext() OVERRIDE {
243 virtual bool OffTheRecord() OVERRIDE {
244 if (filter()->OffTheRecord())
246 if (GetContentClient()->browser()->AllowSaveLocalState(context_))
249 // For now, only disallow storing data for Flash <http://crbug.com/97319>.
250 for (size_t i = 0; i < info_.mime_types.size(); ++i) {
251 if (info_.mime_types[i].mime_type == kFlashPluginSwfMimeType)
257 virtual void SetPluginInfo(const WebPluginInfo& info) OVERRIDE {
261 virtual void OnFoundPluginProcessHost(PluginProcessHost* host) OVERRIDE {
266 virtual void OnSentPluginChannelRequest() OVERRIDE {
267 sent_plugin_channel_request_ = true;
270 virtual void OnChannelOpened(const IPC::ChannelHandle& handle) OVERRIDE {
271 WriteReplyAndDeleteThis(handle);
274 virtual void OnError() OVERRIDE {
275 WriteReplyAndDeleteThis(IPC::ChannelHandle());
278 PluginProcessHost* host() const {
282 bool sent_plugin_channel_request() const {
283 return sent_plugin_channel_request_;
291 void WriteReplyAndDeleteThis(const IPC::ChannelHandle& handle) {
292 FrameHostMsg_OpenChannelToPlugin::WriteReplyParams(reply_msg(),
294 filter()->OnCompletedOpenChannelToNpapiPlugin(this);
295 SendReplyAndDeleteThis();
298 ResourceContext* context_;
300 PluginProcessHost* host_;
301 bool sent_plugin_channel_request_;
304 RenderMessageFilter::RenderMessageFilter(
305 int render_process_id,
306 PluginServiceImpl* plugin_service,
307 BrowserContext* browser_context,
308 net::URLRequestContextGetter* request_context,
309 RenderWidgetHelper* render_widget_helper,
310 media::AudioManager* audio_manager,
311 MediaInternals* media_internals,
312 DOMStorageContextWrapper* dom_storage_context)
313 : BrowserMessageFilter(
314 kFilteredMessageClasses, arraysize(kFilteredMessageClasses)),
315 resource_dispatcher_host_(ResourceDispatcherHostImpl::Get()),
316 plugin_service_(plugin_service),
317 profile_data_directory_(browser_context->GetPath()),
318 request_context_(request_context),
319 resource_context_(browser_context->GetResourceContext()),
320 render_widget_helper_(render_widget_helper),
321 incognito_(browser_context->IsOffTheRecord()),
322 dom_storage_context_(dom_storage_context),
323 render_process_id_(render_process_id),
325 audio_manager_(audio_manager),
326 media_internals_(media_internals) {
327 DCHECK(request_context_.get());
329 render_widget_helper_->Init(render_process_id_, resource_dispatcher_host_);
332 RenderMessageFilter::~RenderMessageFilter() {
333 // This function should be called on the IO thread.
334 DCHECK_CURRENTLY_ON(BrowserThread::IO);
335 DCHECK(plugin_host_clients_.empty());
336 HostSharedBitmapManager::current()->ProcessRemoved(PeerHandle());
339 void RenderMessageFilter::OnChannelClosing() {
340 #if defined(ENABLE_PLUGINS)
341 for (std::set<OpenChannelToNpapiPluginCallback*>::iterator it =
342 plugin_host_clients_.begin(); it != plugin_host_clients_.end(); ++it) {
343 OpenChannelToNpapiPluginCallback* client = *it;
344 if (client->host()) {
345 if (client->sent_plugin_channel_request()) {
346 client->host()->CancelSentRequest(client);
348 client->host()->CancelPendingRequest(client);
351 plugin_service_->CancelOpenChannelToNpapiPlugin(client);
355 #endif // defined(ENABLE_PLUGINS)
356 plugin_host_clients_.clear();
359 void RenderMessageFilter::OnChannelConnected(int32 peer_id) {
360 base::ProcessHandle handle = PeerHandle();
361 #if defined(OS_MACOSX)
362 process_metrics_.reset(base::ProcessMetrics::CreateProcessMetrics(handle,
365 process_metrics_.reset(base::ProcessMetrics::CreateProcessMetrics(handle));
367 cpu_usage_ = process_metrics_->GetCPUUsage(); // Initialize CPU usage counters
368 cpu_usage_sample_time_ = base::TimeTicks::Now();
371 bool RenderMessageFilter::OnMessageReceived(const IPC::Message& message) {
373 IPC_BEGIN_MESSAGE_MAP(RenderMessageFilter, message)
375 IPC_MESSAGE_HANDLER(ViewHostMsg_PreCacheFontCharacters,
376 OnPreCacheFontCharacters)
378 IPC_MESSAGE_HANDLER(ViewHostMsg_GetProcessMemorySizes,
379 OnGetProcessMemorySizes)
380 IPC_MESSAGE_HANDLER(ViewHostMsg_GenerateRoutingID, OnGenerateRoutingID)
381 IPC_MESSAGE_HANDLER(ViewHostMsg_CreateWindow, OnCreateWindow)
382 IPC_MESSAGE_HANDLER(ViewHostMsg_CreateWidget, OnCreateWidget)
383 IPC_MESSAGE_HANDLER(ViewHostMsg_CreateFullscreenWidget,
384 OnCreateFullscreenWidget)
385 IPC_MESSAGE_HANDLER(ViewHostMsg_SetCookie, OnSetCookie)
386 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_GetCookies, OnGetCookies)
387 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_GetRawCookies, OnGetRawCookies)
388 IPC_MESSAGE_HANDLER(ViewHostMsg_DeleteCookie, OnDeleteCookie)
389 IPC_MESSAGE_HANDLER(ViewHostMsg_CookiesEnabled, OnCookiesEnabled)
390 #if defined(OS_MACOSX)
391 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_LoadFont, OnLoadFont)
393 IPC_MESSAGE_HANDLER(ViewHostMsg_DownloadUrl, OnDownloadUrl)
394 #if defined(ENABLE_PLUGINS)
395 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_GetPlugins, OnGetPlugins)
396 IPC_MESSAGE_HANDLER(FrameHostMsg_GetPluginInfo, OnGetPluginInfo)
397 IPC_MESSAGE_HANDLER_DELAY_REPLY(FrameHostMsg_OpenChannelToPlugin,
398 OnOpenChannelToPlugin)
399 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_OpenChannelToPepperPlugin,
400 OnOpenChannelToPepperPlugin)
401 IPC_MESSAGE_HANDLER(ViewHostMsg_DidCreateOutOfProcessPepperInstance,
402 OnDidCreateOutOfProcessPepperInstance)
403 IPC_MESSAGE_HANDLER(ViewHostMsg_DidDeleteOutOfProcessPepperInstance,
404 OnDidDeleteOutOfProcessPepperInstance)
405 IPC_MESSAGE_HANDLER(ViewHostMsg_OpenChannelToPpapiBroker,
406 OnOpenChannelToPpapiBroker)
408 #if defined(OS_MACOSX)
409 IPC_MESSAGE_HANDLER_GENERIC(ViewHostMsg_SwapCompositorFrame,
410 RenderWidgetResizeHelper::Get()->PostRendererProcessMsg(
411 render_process_id_, message))
412 IPC_MESSAGE_HANDLER_GENERIC(ViewHostMsg_UpdateRect,
413 RenderWidgetResizeHelper::Get()->PostRendererProcessMsg(
414 render_process_id_, message))
416 IPC_MESSAGE_HANDLER(DesktopNotificationHostMsg_CheckPermission,
417 OnCheckNotificationPermission)
418 IPC_MESSAGE_HANDLER(ChildProcessHostMsg_SyncAllocateSharedMemory,
419 OnAllocateSharedMemory)
420 IPC_MESSAGE_HANDLER_DELAY_REPLY(
421 ChildProcessHostMsg_SyncAllocateSharedBitmap, OnAllocateSharedBitmap)
422 IPC_MESSAGE_HANDLER(ChildProcessHostMsg_AllocatedSharedBitmap,
423 OnAllocatedSharedBitmap)
424 IPC_MESSAGE_HANDLER(ChildProcessHostMsg_DeletedSharedBitmap,
425 OnDeletedSharedBitmap)
426 #if defined(OS_POSIX) && !defined(OS_ANDROID)
427 IPC_MESSAGE_HANDLER(ViewHostMsg_AllocTransportDIB, OnAllocTransportDIB)
428 IPC_MESSAGE_HANDLER(ViewHostMsg_FreeTransportDIB, OnFreeTransportDIB)
430 IPC_MESSAGE_HANDLER(ViewHostMsg_DidGenerateCacheableMetadata,
431 OnCacheableMetadataAvailable)
432 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_Keygen, OnKeygen)
433 IPC_MESSAGE_HANDLER(ViewHostMsg_GetCPUUsage, OnGetCPUUsage)
434 IPC_MESSAGE_HANDLER(ViewHostMsg_GetAudioHardwareConfig,
435 OnGetAudioHardwareConfig)
437 IPC_MESSAGE_HANDLER(ViewHostMsg_GetMonitorColorProfile,
438 OnGetMonitorColorProfile)
440 IPC_MESSAGE_HANDLER(ViewHostMsg_MediaLogEvents, OnMediaLogEvents)
441 IPC_MESSAGE_HANDLER(ViewHostMsg_Are3DAPIsBlocked, OnAre3DAPIsBlocked)
442 IPC_MESSAGE_HANDLER(ViewHostMsg_DidLose3DContext, OnDidLose3DContext)
443 #if defined(OS_ANDROID)
444 IPC_MESSAGE_HANDLER(ViewHostMsg_RunWebAudioMediaCodec, OnWebAudioMediaCodec)
446 IPC_MESSAGE_HANDLER(FrameHostMsg_AddNavigationTransitionData,
447 OnAddNavigationTransitionData)
448 IPC_MESSAGE_UNHANDLED(handled = false)
449 IPC_END_MESSAGE_MAP()
454 void RenderMessageFilter::OnDestruct() const {
455 BrowserThread::DeleteOnIOThread::Destruct(this);
458 base::TaskRunner* RenderMessageFilter::OverrideTaskRunnerForMessage(
459 const IPC::Message& message) {
461 // Windows monitor profile must be read from a file.
462 if (message.type() == ViewHostMsg_GetMonitorColorProfile::ID)
463 return BrowserThread::GetBlockingPool();
465 // Always query audio device parameters on the audio thread.
466 if (message.type() == ViewHostMsg_GetAudioHardwareConfig::ID)
467 return audio_manager_->GetTaskRunner().get();
471 bool RenderMessageFilter::OffTheRecord() const {
475 void RenderMessageFilter::OnCreateWindow(
476 const ViewHostMsg_CreateWindow_Params& params,
478 int* main_frame_route_id,
480 int64* cloned_session_storage_namespace_id) {
481 bool no_javascript_access;
483 // Merge the additional features into the WebWindowFeatures struct before we
485 blink::WebVector<blink::WebString> additional_features(
486 params.additional_features.size());
488 for (size_t i = 0; i < params.additional_features.size(); ++i)
489 additional_features[i] = blink::WebString(params.additional_features[i]);
491 blink::WebWindowFeatures features = params.features;
492 features.additionalFeatures.swap(additional_features);
494 bool can_create_window =
495 GetContentClient()->browser()->CanCreateWindow(
497 params.opener_top_level_frame_url,
498 params.opener_security_origin,
499 params.window_container_type,
505 params.opener_suppressed,
509 &no_javascript_access);
511 if (!can_create_window) {
512 *route_id = MSG_ROUTING_NONE;
513 *main_frame_route_id = MSG_ROUTING_NONE;
515 *cloned_session_storage_namespace_id = 0;
519 // This will clone the sessionStorage for namespace_id_to_clone.
520 scoped_refptr<SessionStorageNamespaceImpl> cloned_namespace =
521 new SessionStorageNamespaceImpl(dom_storage_context_.get(),
522 params.session_storage_namespace_id);
523 *cloned_session_storage_namespace_id = cloned_namespace->id();
525 render_widget_helper_->CreateNewWindow(params,
526 no_javascript_access,
531 cloned_namespace.get());
534 void RenderMessageFilter::OnCreateWidget(int opener_id,
535 blink::WebPopupType popup_type,
538 render_widget_helper_->CreateNewWidget(
539 opener_id, popup_type, route_id, surface_id);
542 void RenderMessageFilter::OnCreateFullscreenWidget(int opener_id,
545 render_widget_helper_->CreateNewFullscreenWidget(
546 opener_id, route_id, surface_id);
549 void RenderMessageFilter::OnGetProcessMemorySizes(size_t* private_bytes,
550 size_t* shared_bytes) {
551 DCHECK_CURRENTLY_ON(BrowserThread::IO);
552 using base::ProcessMetrics;
553 #if !defined(OS_MACOSX) || defined(OS_IOS)
554 scoped_ptr<ProcessMetrics> metrics(ProcessMetrics::CreateProcessMetrics(
557 scoped_ptr<ProcessMetrics> metrics(ProcessMetrics::CreateProcessMetrics(
558 PeerHandle(), content::BrowserChildProcessHost::GetPortProvider()));
560 if (!metrics->GetMemoryBytes(private_bytes, shared_bytes)) {
566 void RenderMessageFilter::OnSetCookie(int render_frame_id,
568 const GURL& first_party_for_cookies,
569 const std::string& cookie) {
570 ChildProcessSecurityPolicyImpl* policy =
571 ChildProcessSecurityPolicyImpl::GetInstance();
572 if (!policy->CanAccessCookiesForOrigin(render_process_id_, url))
575 net::CookieOptions options;
576 if (GetContentClient()->browser()->AllowSetCookie(
577 url, first_party_for_cookies, cookie, resource_context_,
578 render_process_id_, render_frame_id, &options)) {
579 net::CookieStore* cookie_store = GetCookieStoreForURL(url);
580 // Pass a null callback since we don't care about when the 'set' completes.
581 cookie_store->SetCookieWithOptionsAsync(
582 url, cookie, options, net::CookieStore::SetCookiesCallback());
586 void RenderMessageFilter::OnGetCookies(int render_frame_id,
588 const GURL& first_party_for_cookies,
589 IPC::Message* reply_msg) {
590 ChildProcessSecurityPolicyImpl* policy =
591 ChildProcessSecurityPolicyImpl::GetInstance();
592 if (!policy->CanAccessCookiesForOrigin(render_process_id_, url)) {
593 SendGetCookiesResponse(reply_msg, std::string());
597 // If we crash here, figure out what URL the renderer was requesting.
598 // http://crbug.com/99242
600 base::strlcpy(url_buf, url.spec().c_str(), arraysize(url_buf));
601 base::debug::Alias(url_buf);
603 net::CookieStore* cookie_store = GetCookieStoreForURL(url);
604 cookie_store->GetAllCookiesForURLAsync(
605 url, base::Bind(&RenderMessageFilter::CheckPolicyForCookies, this,
606 render_frame_id, url, first_party_for_cookies,
610 void RenderMessageFilter::OnGetRawCookies(
612 const GURL& first_party_for_cookies,
613 IPC::Message* reply_msg) {
614 ChildProcessSecurityPolicyImpl* policy =
615 ChildProcessSecurityPolicyImpl::GetInstance();
616 // Only return raw cookies to trusted renderers or if this request is
617 // not targeted to an an external host like ChromeFrame.
618 // TODO(ananta) We need to support retreiving raw cookies from external
620 if (!policy->CanReadRawCookies(render_process_id_) ||
621 !policy->CanAccessCookiesForOrigin(render_process_id_, url)) {
622 SendGetRawCookiesResponse(reply_msg, net::CookieList());
626 // We check policy here to avoid sending back cookies that would not normally
627 // be applied to outbound requests for the given URL. Since this cookie info
628 // is visible in the developer tools, it is helpful to make it match reality.
629 net::CookieStore* cookie_store = GetCookieStoreForURL(url);
630 cookie_store->GetAllCookiesForURLAsync(
631 url, base::Bind(&RenderMessageFilter::SendGetRawCookiesResponse,
635 void RenderMessageFilter::OnDeleteCookie(const GURL& url,
636 const std::string& cookie_name) {
637 ChildProcessSecurityPolicyImpl* policy =
638 ChildProcessSecurityPolicyImpl::GetInstance();
639 if (!policy->CanAccessCookiesForOrigin(render_process_id_, url))
642 net::CookieStore* cookie_store = GetCookieStoreForURL(url);
643 cookie_store->DeleteCookieAsync(url, cookie_name, base::Closure());
646 void RenderMessageFilter::OnCookiesEnabled(
649 const GURL& first_party_for_cookies,
650 bool* cookies_enabled) {
651 // TODO(ananta): If this render view is associated with an automation channel,
652 // aka ChromeFrame then we need to retrieve cookie settings from the external
654 *cookies_enabled = GetContentClient()->browser()->AllowGetCookie(
655 url, first_party_for_cookies, net::CookieList(), resource_context_,
656 render_process_id_, render_frame_id);
659 #if defined(OS_MACOSX)
660 void RenderMessageFilter::OnLoadFont(const FontDescriptor& font,
661 IPC::Message* reply_msg) {
662 FontLoader::Result* result = new FontLoader::Result;
664 BrowserThread::PostTaskAndReply(
665 BrowserThread::FILE, FROM_HERE,
666 base::Bind(&FontLoader::LoadFont, font, result),
667 base::Bind(&RenderMessageFilter::SendLoadFontReply, this, reply_msg,
668 base::Owned(result)));
671 void RenderMessageFilter::SendLoadFontReply(IPC::Message* reply,
672 FontLoader::Result* result) {
673 base::SharedMemoryHandle handle;
674 if (result->font_data_size == 0 || result->font_id == 0) {
675 result->font_data_size = 0;
677 handle = base::SharedMemory::NULLHandle();
679 result->font_data.GiveToProcess(base::GetCurrentProcessHandle(), &handle);
681 ViewHostMsg_LoadFont::WriteReplyParams(
682 reply, result->font_data_size, handle, result->font_id);
687 #if defined(ENABLE_PLUGINS)
688 void RenderMessageFilter::OnGetPlugins(
690 IPC::Message* reply_msg) {
691 // Don't refresh if the specified threshold has not been passed. Note that
692 // this check is performed before off-loading to the file thread. The reason
693 // we do this is that some pages tend to request that the list of plugins be
694 // refreshed at an excessive rate. This instigates disk scanning, as the list
695 // is accumulated by doing multiple reads from disk. This effect is
696 // multiplied when we have several pages requesting this operation.
698 const base::TimeDelta threshold = base::TimeDelta::FromSeconds(
699 kPluginsRefreshThresholdInSeconds);
700 const base::TimeTicks now = base::TimeTicks::Now();
701 if (now - last_plugin_refresh_time_ >= threshold) {
702 // Only refresh if the threshold hasn't been exceeded yet.
703 PluginServiceImpl::GetInstance()->RefreshPlugins();
704 last_plugin_refresh_time_ = now;
708 PluginServiceImpl::GetInstance()->GetPlugins(
709 base::Bind(&RenderMessageFilter::GetPluginsCallback, this, reply_msg));
712 void RenderMessageFilter::GetPluginsCallback(
713 IPC::Message* reply_msg,
714 const std::vector<WebPluginInfo>& all_plugins) {
715 // Filter the plugin list.
716 PluginServiceFilter* filter = PluginServiceImpl::GetInstance()->GetFilter();
717 std::vector<WebPluginInfo> plugins;
719 int child_process_id = -1;
720 int routing_id = MSG_ROUTING_NONE;
721 for (size_t i = 0; i < all_plugins.size(); ++i) {
722 // Copy because the filter can mutate.
723 WebPluginInfo plugin(all_plugins[i]);
724 if (!filter || filter->IsPluginAvailable(child_process_id,
730 plugins.push_back(plugin);
734 ViewHostMsg_GetPlugins::WriteReplyParams(reply_msg, plugins);
738 void RenderMessageFilter::OnGetPluginInfo(
741 const GURL& page_url,
742 const std::string& mime_type,
745 std::string* actual_mime_type) {
746 bool allow_wildcard = true;
747 *found = plugin_service_->GetPluginInfo(
748 render_process_id_, render_frame_id, resource_context_,
749 url, page_url, mime_type, allow_wildcard,
750 NULL, info, actual_mime_type);
753 void RenderMessageFilter::OnOpenChannelToPlugin(int render_frame_id,
755 const GURL& policy_url,
756 const std::string& mime_type,
757 IPC::Message* reply_msg) {
758 OpenChannelToNpapiPluginCallback* client =
759 new OpenChannelToNpapiPluginCallback(this, resource_context_, reply_msg);
760 DCHECK(!ContainsKey(plugin_host_clients_, client));
761 plugin_host_clients_.insert(client);
762 plugin_service_->OpenChannelToNpapiPlugin(
763 render_process_id_, render_frame_id,
764 url, policy_url, mime_type, client);
767 void RenderMessageFilter::OnOpenChannelToPepperPlugin(
768 const base::FilePath& path,
769 IPC::Message* reply_msg) {
770 plugin_service_->OpenChannelToPpapiPlugin(
773 profile_data_directory_,
774 new OpenChannelToPpapiPluginCallback(this, resource_context_, reply_msg));
777 void RenderMessageFilter::OnDidCreateOutOfProcessPepperInstance(
780 PepperRendererInstanceData instance_data,
782 // It's important that we supply the render process ID ourselves based on the
783 // channel the message arrived on. We use the
784 // PP_Instance -> (process id, view id)
785 // mapping to decide how to handle messages received from the (untrusted)
786 // plugin, so an exploited renderer must not be able to insert fake mappings
787 // that may allow it access to other render processes.
788 DCHECK_EQ(0, instance_data.render_process_id);
789 instance_data.render_process_id = render_process_id_;
791 // We provide the BrowserPpapiHost to the embedder, so it's safe to cast.
792 BrowserPpapiHostImpl* host = static_cast<BrowserPpapiHostImpl*>(
793 GetContentClient()->browser()->GetExternalBrowserPpapiHost(
796 host->AddInstance(pp_instance, instance_data);
798 PpapiPluginProcessHost::DidCreateOutOfProcessInstance(
799 plugin_child_id, pp_instance, instance_data);
803 void RenderMessageFilter::OnDidDeleteOutOfProcessPepperInstance(
808 // We provide the BrowserPpapiHost to the embedder, so it's safe to cast.
809 BrowserPpapiHostImpl* host = static_cast<BrowserPpapiHostImpl*>(
810 GetContentClient()->browser()->GetExternalBrowserPpapiHost(
813 host->DeleteInstance(pp_instance);
815 PpapiPluginProcessHost::DidDeleteOutOfProcessInstance(
816 plugin_child_id, pp_instance);
820 void RenderMessageFilter::OnOpenChannelToPpapiBroker(
822 const base::FilePath& path) {
823 plugin_service_->OpenChannelToPpapiBroker(
826 new OpenChannelToPpapiBrokerCallback(this, routing_id));
828 #endif // defined(ENABLE_PLUGINS)
830 void RenderMessageFilter::OnGenerateRoutingID(int* route_id) {
831 *route_id = render_widget_helper_->GetNextRoutingID();
834 void RenderMessageFilter::OnGetCPUUsage(int* cpu_usage) {
835 base::TimeTicks now = base::TimeTicks::Now();
836 int64 since_last_sample_ms = (now - cpu_usage_sample_time_).InMilliseconds();
837 if (since_last_sample_ms > kCPUUsageSampleIntervalMs) {
838 cpu_usage_sample_time_ = now;
839 cpu_usage_ = static_cast<int>(process_metrics_->GetCPUUsage());
841 *cpu_usage = cpu_usage_;
844 void RenderMessageFilter::OnGetAudioHardwareConfig(
845 media::AudioParameters* input_params,
846 media::AudioParameters* output_params) {
847 DCHECK(input_params);
848 DCHECK(output_params);
849 *output_params = audio_manager_->GetDefaultOutputStreamParameters();
851 // TODO(henrika): add support for all available input devices.
852 *input_params = audio_manager_->GetInputStreamParameters(
853 media::AudioManagerBase::kDefaultDeviceId);
857 void RenderMessageFilter::OnGetMonitorColorProfile(std::vector<char>* profile) {
858 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO));
859 *profile = g_color_profile.Get().profile();
863 void RenderMessageFilter::OnDownloadUrl(int render_view_id,
865 const Referrer& referrer,
866 const base::string16& suggested_name,
867 const bool use_prompt) {
868 scoped_ptr<DownloadSaveInfo> save_info(new DownloadSaveInfo());
869 save_info->suggested_name = suggested_name;
870 save_info->prompt_for_save_location = use_prompt;
872 // There may be a special cookie store that we could use for this download,
873 // rather than the default one. Since this feature is generally only used for
874 // proper render views, and not downloads, we do not need to retrieve the
875 // special cookie store here, but just initialize the request to use the
876 // default cookie store.
877 // TODO(tburkard): retrieve the appropriate special cookie store, if this
878 // is ever to be used for downloads as well.
879 scoped_ptr<net::URLRequest> request(
880 resource_context_->GetRequestContext()->CreateRequest(
881 url, net::DEFAULT_PRIORITY, NULL, NULL));
882 RecordDownloadSource(INITIATED_BY_RENDERER);
883 resource_dispatcher_host_->BeginDownload(
886 true, // is_content_initiated
892 content::DownloadItem::kInvalidId,
893 ResourceDispatcherHostImpl::DownloadStartedCallback());
896 void RenderMessageFilter::OnCheckNotificationPermission(
897 const GURL& source_origin, int* result) {
898 #if defined(ENABLE_NOTIFICATIONS)
899 *result = GetContentClient()->browser()->
900 CheckDesktopNotificationPermission(source_origin, resource_context_,
903 *result = blink::WebNotificationPresenter::PermissionAllowed;
907 void RenderMessageFilter::OnAllocateSharedMemory(
909 base::SharedMemoryHandle* handle) {
910 ChildProcessHostImpl::AllocateSharedMemory(
911 buffer_size, PeerHandle(), handle);
914 void RenderMessageFilter::AllocateSharedBitmapOnFileThread(
916 const cc::SharedBitmapId& id,
917 IPC::Message* reply_msg) {
918 base::SharedMemoryHandle handle;
919 HostSharedBitmapManager::current()->AllocateSharedBitmapForChild(
920 PeerHandle(), buffer_size, id, &handle);
921 ChildProcessHostMsg_SyncAllocateSharedBitmap::WriteReplyParams(reply_msg,
926 void RenderMessageFilter::OnAllocateSharedBitmap(uint32 buffer_size,
927 const cc::SharedBitmapId& id,
928 IPC::Message* reply_msg) {
929 BrowserThread::PostTask(
930 BrowserThread::FILE_USER_BLOCKING,
932 base::Bind(&RenderMessageFilter::AllocateSharedBitmapOnFileThread,
939 void RenderMessageFilter::OnAllocatedSharedBitmap(
941 const base::SharedMemoryHandle& handle,
942 const cc::SharedBitmapId& id) {
943 HostSharedBitmapManager::current()->ChildAllocatedSharedBitmap(
944 buffer_size, handle, PeerHandle(), id);
947 void RenderMessageFilter::OnDeletedSharedBitmap(const cc::SharedBitmapId& id) {
948 HostSharedBitmapManager::current()->ChildDeletedSharedBitmap(id);
951 net::CookieStore* RenderMessageFilter::GetCookieStoreForURL(
953 DCHECK_CURRENTLY_ON(BrowserThread::IO);
955 net::URLRequestContext* context =
956 GetContentClient()->browser()->OverrideRequestContextForURL(
957 url, resource_context_);
959 // If we should use a special URLRequestContext rather than the default one,
960 // return the cookie store of that special URLRequestContext.
962 return context->cookie_store();
964 // Otherwise, if there is a special cookie store to be used for this process,
965 // return that cookie store.
966 net::CookieStore* cookie_store =
967 GetContentClient()->browser()->OverrideCookieStoreForRenderProcess(
972 // Otherwise, return the cookie store of the default request context used
973 // for this renderer.
974 return request_context_->GetURLRequestContext()->cookie_store();
977 #if defined(OS_POSIX) && !defined(OS_ANDROID)
978 void RenderMessageFilter::OnAllocTransportDIB(
979 uint32 size, bool cache_in_browser, TransportDIB::Handle* handle) {
980 render_widget_helper_->AllocTransportDIB(size, cache_in_browser, handle);
983 void RenderMessageFilter::OnFreeTransportDIB(
984 TransportDIB::Id dib_id) {
985 render_widget_helper_->FreeTransportDIB(dib_id);
989 void RenderMessageFilter::OnCacheableMetadataAvailable(
991 double expected_response_time,
992 const std::vector<char>& data) {
993 net::HttpCache* cache = request_context_->GetURLRequestContext()->
994 http_transaction_factory()->GetCache();
997 // Use the same priority for the metadata write as for script
998 // resources (see defaultPriorityForResourceType() in WebKit's
999 // CachedResource.cpp). Note that WebURLRequest::PriorityMedium
1000 // corresponds to net::LOW (see ConvertWebKitPriorityToNetPriority()
1001 // in weburlloader_impl.cc).
1002 const net::RequestPriority kPriority = net::LOW;
1003 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(data.size()));
1004 memcpy(buf->data(), &data.front(), data.size());
1005 cache->WriteMetadata(url,
1007 base::Time::FromDoubleT(expected_response_time),
1012 void RenderMessageFilter::OnKeygen(uint32 key_size_index,
1013 const std::string& challenge_string,
1015 IPC::Message* reply_msg) {
1016 // Map displayed strings indicating level of keysecurity in the <keygen>
1017 // menu to the key size in bits. (See SSLKeyGeneratorChromium.cpp in WebCore.)
1018 int key_size_in_bits;
1019 switch (key_size_index) {
1021 key_size_in_bits = 2048;
1024 key_size_in_bits = 1024;
1027 DCHECK(false) << "Illegal key_size_index " << key_size_index;
1028 ViewHostMsg_Keygen::WriteReplyParams(reply_msg, std::string());
1033 resource_context_->CreateKeygenHandler(
1038 &RenderMessageFilter::PostKeygenToWorkerThread, this, reply_msg));
1041 void RenderMessageFilter::PostKeygenToWorkerThread(
1042 IPC::Message* reply_msg,
1043 scoped_ptr<net::KeygenHandler> keygen_handler) {
1044 VLOG(1) << "Dispatching keygen task to worker pool.";
1045 // Dispatch to worker pool, so we do not block the IO thread.
1046 if (!base::WorkerPool::PostTask(
1048 base::Bind(&RenderMessageFilter::OnKeygenOnWorkerThread,
1050 base::Passed(&keygen_handler),
1053 NOTREACHED() << "Failed to dispatch keygen task to worker pool";
1054 ViewHostMsg_Keygen::WriteReplyParams(reply_msg, std::string());
1059 void RenderMessageFilter::OnKeygenOnWorkerThread(
1060 scoped_ptr<net::KeygenHandler> keygen_handler,
1061 IPC::Message* reply_msg) {
1064 // Generate a signed public key and challenge, then send it back.
1065 ViewHostMsg_Keygen::WriteReplyParams(
1067 keygen_handler->GenKeyAndSignChallenge());
1071 void RenderMessageFilter::OnMediaLogEvents(
1072 const std::vector<media::MediaLogEvent>& events) {
1073 if (media_internals_)
1074 media_internals_->OnMediaEvents(render_process_id_, events);
1077 void RenderMessageFilter::CheckPolicyForCookies(
1078 int render_frame_id,
1080 const GURL& first_party_for_cookies,
1081 IPC::Message* reply_msg,
1082 const net::CookieList& cookie_list) {
1083 net::CookieStore* cookie_store = GetCookieStoreForURL(url);
1084 // Check the policy for get cookies, and pass cookie_list to the
1085 // TabSpecificContentSetting for logging purpose.
1086 if (GetContentClient()->browser()->AllowGetCookie(
1087 url, first_party_for_cookies, cookie_list, resource_context_,
1088 render_process_id_, render_frame_id)) {
1089 // Gets the cookies from cookie store if allowed.
1090 cookie_store->GetCookiesWithOptionsAsync(
1091 url, net::CookieOptions(),
1092 base::Bind(&RenderMessageFilter::SendGetCookiesResponse,
1095 SendGetCookiesResponse(reply_msg, std::string());
1099 void RenderMessageFilter::SendGetCookiesResponse(IPC::Message* reply_msg,
1100 const std::string& cookies) {
1101 ViewHostMsg_GetCookies::WriteReplyParams(reply_msg, cookies);
1105 void RenderMessageFilter::SendGetRawCookiesResponse(
1106 IPC::Message* reply_msg,
1107 const net::CookieList& cookie_list) {
1108 std::vector<CookieData> cookies;
1109 for (size_t i = 0; i < cookie_list.size(); ++i)
1110 cookies.push_back(CookieData(cookie_list[i]));
1111 ViewHostMsg_GetRawCookies::WriteReplyParams(reply_msg, cookies);
1115 void RenderMessageFilter::OnCompletedOpenChannelToNpapiPlugin(
1116 OpenChannelToNpapiPluginCallback* client) {
1117 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1118 DCHECK(ContainsKey(plugin_host_clients_, client));
1119 plugin_host_clients_.erase(client);
1122 void RenderMessageFilter::OnAre3DAPIsBlocked(int render_view_id,
1123 const GURL& top_origin_url,
1124 ThreeDAPIType requester,
1126 *blocked = GpuDataManagerImpl::GetInstance()->Are3DAPIsBlocked(
1127 top_origin_url, render_process_id_, render_view_id, requester);
1130 void RenderMessageFilter::OnDidLose3DContext(
1131 const GURL& top_origin_url,
1132 ThreeDAPIType /* unused */,
1133 int arb_robustness_status_code) {
1134 #if defined(OS_MACOSX)
1135 // TODO(kbr): this file indirectly includes npapi.h, which on Mac
1136 // OS pulls in the system OpenGL headers. For some
1137 // not-yet-investigated reason this breaks the build with the 10.6
1138 // SDK but not 10.7. For now work around this in a way compatible
1139 // with the Khronos headers.
1140 #ifndef GL_GUILTY_CONTEXT_RESET_ARB
1141 #define GL_GUILTY_CONTEXT_RESET_ARB 0x8253
1143 #ifndef GL_INNOCENT_CONTEXT_RESET_ARB
1144 #define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254
1146 #ifndef GL_UNKNOWN_CONTEXT_RESET_ARB
1147 #define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255
1151 GpuDataManagerImpl::DomainGuilt guilt;
1152 switch (arb_robustness_status_code) {
1153 case GL_GUILTY_CONTEXT_RESET_ARB:
1154 guilt = GpuDataManagerImpl::DOMAIN_GUILT_KNOWN;
1156 case GL_UNKNOWN_CONTEXT_RESET_ARB:
1157 guilt = GpuDataManagerImpl::DOMAIN_GUILT_UNKNOWN;
1160 // Ignore lost contexts known to be innocent.
1164 GpuDataManagerImpl::GetInstance()->BlockDomainFrom3DAPIs(
1165 top_origin_url, guilt);
1169 void RenderMessageFilter::OnPreCacheFontCharacters(const LOGFONT& font,
1170 const base::string16& str) {
1171 // TODO(scottmg): pdf/ppapi still require the renderer to be able to precache
1172 // GDI fonts (http://crbug.com/383227), even when using DirectWrite.
1173 // Eventually this shouldn't be added and should be moved to
1174 // FontCacheDispatcher too. http://crbug.com/356346.
1176 // First, comments from FontCacheDispatcher::OnPreCacheFont do apply here too.
1177 // Except that for True Type fonts,
1178 // GetTextMetrics will not load the font in memory.
1179 // The only way windows seem to load properly, it is to create a similar
1180 // device (like the one in which we print), then do an ExtTextOut,
1181 // as we do in the printing thread, which is sandboxed.
1182 HDC hdc = CreateEnhMetaFile(NULL, NULL, NULL, NULL);
1183 HFONT font_handle = CreateFontIndirect(&font);
1184 DCHECK(NULL != font_handle);
1186 HGDIOBJ old_font = SelectObject(hdc, font_handle);
1187 DCHECK(NULL != old_font);
1189 ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, str.c_str(), str.length(), NULL);
1191 SelectObject(hdc, old_font);
1192 DeleteObject(font_handle);
1194 HENHMETAFILE metafile = CloseEnhMetaFile(hdc);
1197 DeleteEnhMetaFile(metafile);
1202 #if defined(OS_ANDROID)
1203 void RenderMessageFilter::OnWebAudioMediaCodec(
1204 base::SharedMemoryHandle encoded_data_handle,
1205 base::FileDescriptor pcm_output,
1206 uint32_t data_size) {
1207 // Let a WorkerPool handle this request since the WebAudio
1208 // MediaCodec bridge is slow and can block while sending the data to
1210 base::WorkerPool::PostTask(
1212 base::Bind(&media::WebAudioMediaCodecBridge::RunWebAudioMediaCodec,
1213 encoded_data_handle, pcm_output, data_size),
1219 void RenderMessageFilter::OnAddNavigationTransitionData(
1220 int render_frame_id,
1221 const std::string& allowed_destination_host_pattern,
1222 const std::string& selector,
1223 const std::string& markup) {
1224 TransitionRequestManager::GetInstance()->AddPendingTransitionRequestData(
1225 render_process_id_, render_frame_id, allowed_destination_host_pattern,
1229 } // namespace content