render_message_filter.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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. 4 5#include "content/browser/renderer_host/render_message_filter.h" 6 7#include <map> 8 9#include "base/bind.h" 10#include "base/bind_helpers.h" 11#include "base/command_line.h" 12#include "base/debug/alias.h" 13#include "base/numerics/safe_math.h" 14#include "base/strings/sys_string_conversions.h" 15#include "base/strings/utf_string_conversions.h" 16#include "base/threading/thread.h" 17#include "base/threading/worker_pool.h" 18#include "content/browser/browser_main_loop.h" 19#include "content/browser/child_process_security_policy_impl.h" 20#include "content/browser/dom_storage/dom_storage_context_wrapper.h" 21#include "content/browser/dom_storage/session_storage_namespace_impl.h" 22#include "content/browser/download/download_stats.h" 23#include "content/browser/gpu/gpu_data_manager_impl.h" 24#include "content/browser/loader/resource_dispatcher_host_impl.h" 25#include "content/browser/media/media_internals.h" 26#include "content/browser/plugin_process_host.h" 27#include "content/browser/plugin_service_impl.h" 28#include "content/browser/ppapi_plugin_process_host.h" 29#include "content/browser/renderer_host/pepper/pepper_security_helper.h" 30#include "content/browser/renderer_host/render_process_host_impl.h" 31#include "content/browser/renderer_host/render_view_host_delegate.h" 32#include "content/browser/renderer_host/render_widget_helper.h" 33#include "content/common/child_process_host_impl.h" 34#include "content/common/child_process_messages.h" 35#include "content/common/cookie_data.h" 36#include "content/common/desktop_notification_messages.h" 37#include "content/common/frame_messages.h" 38#include "content/common/gpu/client/gpu_memory_buffer_impl.h" 39#include "content/common/gpu/client/gpu_memory_buffer_impl_shm.h" 40#include "content/common/host_shared_bitmap_manager.h" 41#include "content/common/media/media_param_traits.h" 42#include "content/common/view_messages.h" 43#include "content/public/browser/browser_child_process_host.h" 44#include "content/public/browser/browser_context.h" 45#include "content/public/browser/browser_thread.h" 46#include "content/public/browser/content_browser_client.h" 47#include "content/public/browser/download_save_info.h" 48#include "content/public/browser/plugin_service_filter.h" 49#include "content/public/browser/resource_context.h" 50#include "content/public/browser/user_metrics.h" 51#include "content/public/common/content_constants.h" 52#include "content/public/common/content_switches.h" 53#include "content/public/common/context_menu_params.h" 54#include "content/public/common/url_constants.h" 55#include "content/public/common/webplugininfo.h" 56#include "ipc/ipc_channel_handle.h" 57#include "ipc/ipc_platform_file.h" 58#include "media/audio/audio_manager.h" 59#include "media/audio/audio_manager_base.h" 60#include "media/audio/audio_parameters.h" 61#include "media/base/media_log_event.h" 62#include "net/base/io_buffer.h" 63#include "net/base/keygen_handler.h" 64#include "net/base/mime_util.h" 65#include "net/base/request_priority.h" 66#include "net/cookies/canonical_cookie.h" 67#include "net/cookies/cookie_store.h" 68#include "net/http/http_cache.h" 69#include "net/url_request/url_request_context.h" 70#include "net/url_request/url_request_context_getter.h" 71#include "ppapi/shared_impl/file_type_conversion.h" 72#include "third_party/WebKit/public/web/WebNotificationPresenter.h" 73#include "ui/gfx/color_profile.h" 74 75#if defined(OS_MACOSX) 76#include "content/common/gpu/client/gpu_memory_buffer_impl_io_surface.h" 77#include "content/common/mac/font_descriptor.h" 78#include "ui/gl/io_surface_support_mac.h" 79#else 80#include "gpu/GLES2/gl2extchromium.h" 81#include "third_party/khronos/GLES2/gl2.h" 82#include "third_party/khronos/GLES2/gl2ext.h" 83#endif 84#if defined(OS_POSIX) 85#include "base/file_descriptor_posix.h" 86#endif 87#if defined(OS_WIN) 88#include "content/common/font_cache_dispatcher_win.h" 89#include "content/common/sandbox_win.h" 90#endif 91#if defined(OS_ANDROID) 92#include "content/browser/renderer_host/compositor_impl_android.h" 93#include "content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.h" 94#include "media/base/android/webaudio_media_codec_bridge.h" 95#endif 96 97using net::CookieStore; 98 99namespace content { 100namespace { 101 102#if defined(ENABLE_PLUGINS) 103const int kPluginsRefreshThresholdInSeconds = 3; 104#endif 105 106// When two CPU usage queries arrive within this interval, we sample the CPU 107// usage only once and send it as a response for both queries. 108static const int64 kCPUUsageSampleIntervalMs = 900; 109 110const uint32 kFilteredMessageClasses[] = { 111 ChildProcessMsgStart, 112 DesktopNotificationMsgStart, 113 FrameMsgStart, 114 ViewMsgStart, 115}; 116 117#if defined(OS_WIN) 118// On Windows, |g_color_profile| can run on an arbitrary background thread. 119// We avoid races by using LazyInstance's constructor lock to initialize the 120// object. 121base::LazyInstance<gfx::ColorProfile>::Leaky g_color_profile = 122 LAZY_INSTANCE_INITIALIZER; 123#endif 124 125// Common functionality for converting a sync renderer message to a callback 126// function in the browser. Derive from this, create it on the heap when 127// issuing your callback. When done, write your reply parameters into 128// reply_msg(), and then call SendReplyAndDeleteThis(). 129class RenderMessageCompletionCallback { 130 public: 131 RenderMessageCompletionCallback(RenderMessageFilter* filter, 132 IPC::Message* reply_msg) 133 : filter_(filter), 134 reply_msg_(reply_msg) { 135 } 136 137 virtual ~RenderMessageCompletionCallback() { 138 } 139 140 RenderMessageFilter* filter() { return filter_.get(); } 141 IPC::Message* reply_msg() { return reply_msg_; } 142 143 void SendReplyAndDeleteThis() { 144 filter_->Send(reply_msg_); 145 delete this; 146 } 147 148 private: 149 scoped_refptr<RenderMessageFilter> filter_; 150 IPC::Message* reply_msg_; 151}; 152 153class OpenChannelToPpapiPluginCallback 154 : public RenderMessageCompletionCallback, 155 public PpapiPluginProcessHost::PluginClient { 156 public: 157 OpenChannelToPpapiPluginCallback(RenderMessageFilter* filter, 158 ResourceContext* context, 159 IPC::Message* reply_msg) 160 : RenderMessageCompletionCallback(filter, reply_msg), 161 context_(context) { 162 } 163 164 virtual void GetPpapiChannelInfo(base::ProcessHandle* renderer_handle, 165 int* renderer_id) OVERRIDE { 166 *renderer_handle = filter()->PeerHandle(); 167 *renderer_id = filter()->render_process_id(); 168 } 169 170 virtual void OnPpapiChannelOpened(const IPC::ChannelHandle& channel_handle, 171 base::ProcessId plugin_pid, 172 int plugin_child_id) OVERRIDE { 173 ViewHostMsg_OpenChannelToPepperPlugin::WriteReplyParams( 174 reply_msg(), channel_handle, plugin_pid, plugin_child_id); 175 SendReplyAndDeleteThis(); 176 } 177 178 virtual bool OffTheRecord() OVERRIDE { 179 return filter()->OffTheRecord(); 180 } 181 182 virtual ResourceContext* GetResourceContext() OVERRIDE { 183 return context_; 184 } 185 186 private: 187 ResourceContext* context_; 188}; 189 190class OpenChannelToPpapiBrokerCallback 191 : public PpapiPluginProcessHost::BrokerClient { 192 public: 193 OpenChannelToPpapiBrokerCallback(RenderMessageFilter* filter, 194 int routing_id) 195 : filter_(filter), 196 routing_id_(routing_id) { 197 } 198 199 virtual ~OpenChannelToPpapiBrokerCallback() {} 200 201 virtual void GetPpapiChannelInfo(base::ProcessHandle* renderer_handle, 202 int* renderer_id) OVERRIDE { 203 *renderer_handle = filter_->PeerHandle(); 204 *renderer_id = filter_->render_process_id(); 205 } 206 207 virtual void OnPpapiChannelOpened(const IPC::ChannelHandle& channel_handle, 208 base::ProcessId plugin_pid, 209 int /* plugin_child_id */) OVERRIDE { 210 filter_->Send(new ViewMsg_PpapiBrokerChannelCreated(routing_id_, 211 plugin_pid, 212 channel_handle)); 213 delete this; 214 } 215 216 virtual bool OffTheRecord() OVERRIDE { 217 return filter_->OffTheRecord(); 218 } 219 220 private: 221 scoped_refptr<RenderMessageFilter> filter_; 222 int routing_id_; 223}; 224 225#if defined(OS_MACOSX) 226void AddBooleanValue(CFMutableDictionaryRef dictionary, 227 const CFStringRef key, 228 bool value) { 229 CFDictionaryAddValue( 230 dictionary, key, value ? kCFBooleanTrue : kCFBooleanFalse); 231} 232 233void AddIntegerValue(CFMutableDictionaryRef dictionary, 234 const CFStringRef key, 235 int32 value) { 236 base::ScopedCFTypeRef<CFNumberRef> number( 237 CFNumberCreate(NULL, kCFNumberSInt32Type, &value)); 238 CFDictionaryAddValue(dictionary, key, number.get()); 239} 240#endif 241 242} // namespace 243 244class RenderMessageFilter::OpenChannelToNpapiPluginCallback 245 : public RenderMessageCompletionCallback, 246 public PluginProcessHost::Client { 247 public: 248 OpenChannelToNpapiPluginCallback(RenderMessageFilter* filter, 249 ResourceContext* context, 250 IPC::Message* reply_msg) 251 : RenderMessageCompletionCallback(filter, reply_msg), 252 context_(context), 253 host_(NULL), 254 sent_plugin_channel_request_(false) { 255 } 256 257 virtual int ID() OVERRIDE { 258 return filter()->render_process_id(); 259 } 260 261 virtual ResourceContext* GetResourceContext() OVERRIDE { 262 return context_; 263 } 264 265 virtual bool OffTheRecord() OVERRIDE { 266 if (filter()->OffTheRecord()) 267 return true; 268 if (GetContentClient()->browser()->AllowSaveLocalState(context_)) 269 return false; 270 271 // For now, only disallow storing data for Flash <http://crbug.com/97319>. 272 for (size_t i = 0; i < info_.mime_types.size(); ++i) { 273 if (info_.mime_types[i].mime_type == kFlashPluginSwfMimeType) 274 return true; 275 } 276 return false; 277 } 278 279 virtual void SetPluginInfo(const WebPluginInfo& info) OVERRIDE { 280 info_ = info; 281 } 282 283 virtual void OnFoundPluginProcessHost(PluginProcessHost* host) OVERRIDE { 284 DCHECK(host); 285 host_ = host; 286 } 287 288 virtual void OnSentPluginChannelRequest() OVERRIDE { 289 sent_plugin_channel_request_ = true; 290 } 291 292 virtual void OnChannelOpened(const IPC::ChannelHandle& handle) OVERRIDE { 293 WriteReplyAndDeleteThis(handle); 294 } 295 296 virtual void OnError() OVERRIDE { 297 WriteReplyAndDeleteThis(IPC::ChannelHandle()); 298 } 299 300 PluginProcessHost* host() const { 301 return host_; 302 } 303 304 bool sent_plugin_channel_request() const { 305 return sent_plugin_channel_request_; 306 } 307 308 void Cancel() { 309 delete this; 310 } 311 312 private: 313 void WriteReplyAndDeleteThis(const IPC::ChannelHandle& handle) { 314 FrameHostMsg_OpenChannelToPlugin::WriteReplyParams(reply_msg(), 315 handle, info_); 316 filter()->OnCompletedOpenChannelToNpapiPlugin(this); 317 SendReplyAndDeleteThis(); 318 } 319 320 ResourceContext* context_; 321 WebPluginInfo info_; 322 PluginProcessHost* host_; 323 bool sent_plugin_channel_request_; 324}; 325 326RenderMessageFilter::RenderMessageFilter( 327 int render_process_id, 328 PluginServiceImpl* plugin_service, 329 BrowserContext* browser_context, 330 net::URLRequestContextGetter* request_context, 331 RenderWidgetHelper* render_widget_helper, 332 media::AudioManager* audio_manager, 333 MediaInternals* media_internals, 334 DOMStorageContextWrapper* dom_storage_context) 335 : BrowserMessageFilter( 336 kFilteredMessageClasses, arraysize(kFilteredMessageClasses)), 337 resource_dispatcher_host_(ResourceDispatcherHostImpl::Get()), 338 plugin_service_(plugin_service), 339 profile_data_directory_(browser_context->GetPath()), 340 request_context_(request_context), 341 resource_context_(browser_context->GetResourceContext()), 342 render_widget_helper_(render_widget_helper), 343 incognito_(browser_context->IsOffTheRecord()), 344 dom_storage_context_(dom_storage_context), 345 render_process_id_(render_process_id), 346 cpu_usage_(0), 347 audio_manager_(audio_manager), 348 media_internals_(media_internals) { 349 DCHECK(request_context_.get()); 350 351 render_widget_helper_->Init(render_process_id_, resource_dispatcher_host_); 352} 353 354RenderMessageFilter::~RenderMessageFilter() { 355 // This function should be called on the IO thread. 356 DCHECK_CURRENTLY_ON(BrowserThread::IO); 357 DCHECK(plugin_host_clients_.empty()); 358} 359 360void RenderMessageFilter::OnChannelClosing() { 361 HostSharedBitmapManager::current()->ProcessRemoved(PeerHandle()); 362#if defined(ENABLE_PLUGINS) 363 for (std::set<OpenChannelToNpapiPluginCallback*>::iterator it = 364 plugin_host_clients_.begin(); it != plugin_host_clients_.end(); ++it) { 365 OpenChannelToNpapiPluginCallback* client = *it; 366 if (client->host()) { 367 if (client->sent_plugin_channel_request()) { 368 client->host()->CancelSentRequest(client); 369 } else { 370 client->host()->CancelPendingRequest(client); 371 } 372 } else { 373 plugin_service_->CancelOpenChannelToNpapiPlugin(client); 374 } 375 client->Cancel(); 376 } 377#endif // defined(ENABLE_PLUGINS) 378 plugin_host_clients_.clear(); 379#if defined(OS_ANDROID) 380 CompositorImpl::DestroyAllSurfaceTextures(render_process_id_); 381#endif 382} 383 384void RenderMessageFilter::OnChannelConnected(int32 peer_id) { 385 base::ProcessHandle handle = PeerHandle(); 386#if defined(OS_MACOSX) 387 process_metrics_.reset(base::ProcessMetrics::CreateProcessMetrics(handle, 388 NULL)); 389#else 390 process_metrics_.reset(base::ProcessMetrics::CreateProcessMetrics(handle)); 391#endif 392 cpu_usage_ = process_metrics_->GetCPUUsage(); // Initialize CPU usage counters 393 cpu_usage_sample_time_ = base::TimeTicks::Now(); 394} 395 396bool RenderMessageFilter::OnMessageReceived(const IPC::Message& message) { 397 bool handled = true; 398 IPC_BEGIN_MESSAGE_MAP(RenderMessageFilter, message) 399#if defined(OS_WIN) 400 IPC_MESSAGE_HANDLER(ViewHostMsg_PreCacheFontCharacters, 401 OnPreCacheFontCharacters) 402#endif 403 IPC_MESSAGE_HANDLER(ViewHostMsg_GetProcessMemorySizes, 404 OnGetProcessMemorySizes) 405 IPC_MESSAGE_HANDLER(ViewHostMsg_GenerateRoutingID, OnGenerateRoutingID) 406 IPC_MESSAGE_HANDLER(ViewHostMsg_CreateWindow, OnCreateWindow) 407 IPC_MESSAGE_HANDLER(ViewHostMsg_CreateWidget, OnCreateWidget) 408 IPC_MESSAGE_HANDLER(ViewHostMsg_CreateFullscreenWidget, 409 OnCreateFullscreenWidget) 410 IPC_MESSAGE_HANDLER(ViewHostMsg_SetCookie, OnSetCookie) 411 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_GetCookies, OnGetCookies) 412 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_GetRawCookies, OnGetRawCookies) 413 IPC_MESSAGE_HANDLER(ViewHostMsg_DeleteCookie, OnDeleteCookie) 414 IPC_MESSAGE_HANDLER(ViewHostMsg_CookiesEnabled, OnCookiesEnabled) 415#if defined(OS_MACOSX) 416 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_LoadFont, OnLoadFont) 417#endif 418 IPC_MESSAGE_HANDLER(ViewHostMsg_DownloadUrl, OnDownloadUrl) 419#if defined(ENABLE_PLUGINS) 420 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_GetPlugins, OnGetPlugins) 421 IPC_MESSAGE_HANDLER(FrameHostMsg_GetPluginInfo, OnGetPluginInfo) 422 IPC_MESSAGE_HANDLER_DELAY_REPLY(FrameHostMsg_OpenChannelToPlugin, 423 OnOpenChannelToPlugin) 424 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_OpenChannelToPepperPlugin, 425 OnOpenChannelToPepperPlugin) 426 IPC_MESSAGE_HANDLER(ViewHostMsg_DidCreateOutOfProcessPepperInstance, 427 OnDidCreateOutOfProcessPepperInstance) 428 IPC_MESSAGE_HANDLER(ViewHostMsg_DidDeleteOutOfProcessPepperInstance, 429 OnDidDeleteOutOfProcessPepperInstance) 430 IPC_MESSAGE_HANDLER(ViewHostMsg_OpenChannelToPpapiBroker, 431 OnOpenChannelToPpapiBroker) 432#endif 433 IPC_MESSAGE_HANDLER_GENERIC(ViewHostMsg_SwapCompositorFrame, 434 render_widget_helper_->DidReceiveBackingStoreMsg(message)) 435 IPC_MESSAGE_HANDLER(DesktopNotificationHostMsg_CheckPermission, 436 OnCheckNotificationPermission) 437 IPC_MESSAGE_HANDLER(ChildProcessHostMsg_SyncAllocateSharedMemory, 438 OnAllocateSharedMemory) 439 IPC_MESSAGE_HANDLER(ChildProcessHostMsg_SyncAllocateSharedBitmap, 440 OnAllocateSharedBitmap) 441 IPC_MESSAGE_HANDLER_DELAY_REPLY( 442 ChildProcessHostMsg_SyncAllocateGpuMemoryBuffer, 443 OnAllocateGpuMemoryBuffer) 444 IPC_MESSAGE_HANDLER(ChildProcessHostMsg_AllocatedSharedBitmap, 445 OnAllocatedSharedBitmap) 446 IPC_MESSAGE_HANDLER(ChildProcessHostMsg_DeletedSharedBitmap, 447 OnDeletedSharedBitmap) 448#if defined(OS_POSIX) && !defined(OS_ANDROID) 449 IPC_MESSAGE_HANDLER(ViewHostMsg_AllocTransportDIB, OnAllocTransportDIB) 450 IPC_MESSAGE_HANDLER(ViewHostMsg_FreeTransportDIB, OnFreeTransportDIB) 451#endif 452 IPC_MESSAGE_HANDLER(ViewHostMsg_DidGenerateCacheableMetadata, 453 OnCacheableMetadataAvailable) 454 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_Keygen, OnKeygen) 455 IPC_MESSAGE_HANDLER(ViewHostMsg_GetCPUUsage, OnGetCPUUsage) 456 IPC_MESSAGE_HANDLER(ViewHostMsg_GetAudioHardwareConfig, 457 OnGetAudioHardwareConfig) 458#if defined(OS_WIN) 459 IPC_MESSAGE_HANDLER(ViewHostMsg_GetMonitorColorProfile, 460 OnGetMonitorColorProfile) 461#endif 462 IPC_MESSAGE_HANDLER(ViewHostMsg_MediaLogEvents, OnMediaLogEvents) 463 IPC_MESSAGE_HANDLER(ViewHostMsg_Are3DAPIsBlocked, OnAre3DAPIsBlocked) 464 IPC_MESSAGE_HANDLER(ViewHostMsg_DidLose3DContext, OnDidLose3DContext) 465#if defined(OS_ANDROID) 466 IPC_MESSAGE_HANDLER(ViewHostMsg_RunWebAudioMediaCodec, OnWebAudioMediaCodec) 467#endif 468 IPC_MESSAGE_UNHANDLED(handled = false) 469 IPC_END_MESSAGE_MAP() 470 471 return handled; 472} 473 474void RenderMessageFilter::OnDestruct() const { 475 BrowserThread::DeleteOnIOThread::Destruct(this); 476} 477 478base::TaskRunner* RenderMessageFilter::OverrideTaskRunnerForMessage( 479 const IPC::Message& message) { 480#if defined(OS_WIN) 481 // Windows monitor profile must be read from a file. 482 if (message.type() == ViewHostMsg_GetMonitorColorProfile::ID) 483 return BrowserThread::GetBlockingPool(); 484#endif 485 // Always query audio device parameters on the audio thread. 486 if (message.type() == ViewHostMsg_GetAudioHardwareConfig::ID) 487 return audio_manager_->GetTaskRunner().get(); 488 return NULL; 489} 490 491bool RenderMessageFilter::OffTheRecord() const { 492 return incognito_; 493} 494 495void RenderMessageFilter::OnCreateWindow( 496 const ViewHostMsg_CreateWindow_Params& params, 497 int* route_id, 498 int* main_frame_route_id, 499 int* surface_id, 500 int64* cloned_session_storage_namespace_id) { 501 bool no_javascript_access; 502 503 // Merge the additional features into the WebWindowFeatures struct before we 504 // pass it on. 505 blink::WebVector<blink::WebString> additional_features( 506 params.additional_features.size()); 507 508 for (size_t i = 0; i < params.additional_features.size(); ++i) 509 additional_features[i] = blink::WebString(params.additional_features[i]); 510 511 blink::WebWindowFeatures features = params.features; 512 features.additionalFeatures.swap(additional_features); 513 514 bool can_create_window = 515 GetContentClient()->browser()->CanCreateWindow( 516 params.opener_url, 517 params.opener_top_level_frame_url, 518 params.opener_security_origin, 519 params.window_container_type, 520 params.target_url, 521 params.referrer, 522 params.disposition, 523 features, 524 params.user_gesture, 525 params.opener_suppressed, 526 resource_context_, 527 render_process_id_, 528 params.opener_id, 529 &no_javascript_access); 530 531 if (!can_create_window) { 532 *route_id = MSG_ROUTING_NONE; 533 *main_frame_route_id = MSG_ROUTING_NONE; 534 *surface_id = 0; 535 return; 536 } 537 538 // This will clone the sessionStorage for namespace_id_to_clone. 539 scoped_refptr<SessionStorageNamespaceImpl> cloned_namespace = 540 new SessionStorageNamespaceImpl(dom_storage_context_.get(), 541 params.session_storage_namespace_id); 542 *cloned_session_storage_namespace_id = cloned_namespace->id(); 543 544 render_widget_helper_->CreateNewWindow(params, 545 no_javascript_access, 546 PeerHandle(), 547 route_id, 548 main_frame_route_id, 549 surface_id, 550 cloned_namespace.get()); 551} 552 553void RenderMessageFilter::OnCreateWidget(int opener_id, 554 blink::WebPopupType popup_type, 555 int* route_id, 556 int* surface_id) { 557 render_widget_helper_->CreateNewWidget( 558 opener_id, popup_type, route_id, surface_id); 559} 560 561void RenderMessageFilter::OnCreateFullscreenWidget(int opener_id, 562 int* route_id, 563 int* surface_id) { 564 render_widget_helper_->CreateNewFullscreenWidget( 565 opener_id, route_id, surface_id); 566} 567 568void RenderMessageFilter::OnGetProcessMemorySizes(size_t* private_bytes, 569 size_t* shared_bytes) { 570 DCHECK_CURRENTLY_ON(BrowserThread::IO); 571 using base::ProcessMetrics; 572#if !defined(OS_MACOSX) || defined(OS_IOS) 573 scoped_ptr<ProcessMetrics> metrics(ProcessMetrics::CreateProcessMetrics( 574 PeerHandle())); 575#else 576 scoped_ptr<ProcessMetrics> metrics(ProcessMetrics::CreateProcessMetrics( 577 PeerHandle(), content::BrowserChildProcessHost::GetPortProvider())); 578#endif 579 if (!metrics->GetMemoryBytes(private_bytes, shared_bytes)) { 580 *private_bytes = 0; 581 *shared_bytes = 0; 582 } 583} 584 585void RenderMessageFilter::OnSetCookie(int render_frame_id, 586 const GURL& url, 587 const GURL& first_party_for_cookies, 588 const std::string& cookie) { 589 ChildProcessSecurityPolicyImpl* policy = 590 ChildProcessSecurityPolicyImpl::GetInstance(); 591 if (!policy->CanAccessCookiesForOrigin(render_process_id_, url)) 592 return; 593 594 net::CookieOptions options; 595 if (GetContentClient()->browser()->AllowSetCookie( 596 url, first_party_for_cookies, cookie, resource_context_, 597 render_process_id_, render_frame_id, &options)) { 598 net::CookieStore* cookie_store = GetCookieStoreForURL(url); 599 // Pass a null callback since we don't care about when the 'set' completes. 600 cookie_store->SetCookieWithOptionsAsync( 601 url, cookie, options, net::CookieStore::SetCookiesCallback()); 602 } 603} 604 605void RenderMessageFilter::OnGetCookies(int render_frame_id, 606 const GURL& url, 607 const GURL& first_party_for_cookies, 608 IPC::Message* reply_msg) { 609 ChildProcessSecurityPolicyImpl* policy = 610 ChildProcessSecurityPolicyImpl::GetInstance(); 611 if (!policy->CanAccessCookiesForOrigin(render_process_id_, url)) { 612 SendGetCookiesResponse(reply_msg, std::string()); 613 return; 614 } 615 616 // If we crash here, figure out what URL the renderer was requesting. 617 // http://crbug.com/99242 618 char url_buf[128]; 619 base::strlcpy(url_buf, url.spec().c_str(), arraysize(url_buf)); 620 base::debug::Alias(url_buf); 621 622 net::CookieStore* cookie_store = GetCookieStoreForURL(url); 623 cookie_store->GetAllCookiesForURLAsync( 624 url, base::Bind(&RenderMessageFilter::CheckPolicyForCookies, this, 625 render_frame_id, url, first_party_for_cookies, 626 reply_msg)); 627} 628 629void RenderMessageFilter::OnGetRawCookies( 630 const GURL& url, 631 const GURL& first_party_for_cookies, 632 IPC::Message* reply_msg) { 633 ChildProcessSecurityPolicyImpl* policy = 634 ChildProcessSecurityPolicyImpl::GetInstance(); 635 // Only return raw cookies to trusted renderers or if this request is 636 // not targeted to an an external host like ChromeFrame. 637 // TODO(ananta) We need to support retreiving raw cookies from external 638 // hosts. 639 if (!policy->CanReadRawCookies(render_process_id_) || 640 !policy->CanAccessCookiesForOrigin(render_process_id_, url)) { 641 SendGetRawCookiesResponse(reply_msg, net::CookieList()); 642 return; 643 } 644 645 // We check policy here to avoid sending back cookies that would not normally 646 // be applied to outbound requests for the given URL. Since this cookie info 647 // is visible in the developer tools, it is helpful to make it match reality. 648 net::CookieStore* cookie_store = GetCookieStoreForURL(url); 649 cookie_store->GetAllCookiesForURLAsync( 650 url, base::Bind(&RenderMessageFilter::SendGetRawCookiesResponse, 651 this, reply_msg)); 652} 653 654void RenderMessageFilter::OnDeleteCookie(const GURL& url, 655 const std::string& cookie_name) { 656 ChildProcessSecurityPolicyImpl* policy = 657 ChildProcessSecurityPolicyImpl::GetInstance(); 658 if (!policy->CanAccessCookiesForOrigin(render_process_id_, url)) 659 return; 660 661 net::CookieStore* cookie_store = GetCookieStoreForURL(url); 662 cookie_store->DeleteCookieAsync(url, cookie_name, base::Closure()); 663} 664 665void RenderMessageFilter::OnCookiesEnabled( 666 int render_frame_id, 667 const GURL& url, 668 const GURL& first_party_for_cookies, 669 bool* cookies_enabled) { 670 // TODO(ananta): If this render view is associated with an automation channel, 671 // aka ChromeFrame then we need to retrieve cookie settings from the external 672 // host. 673 *cookies_enabled = GetContentClient()->browser()->AllowGetCookie( 674 url, first_party_for_cookies, net::CookieList(), resource_context_, 675 render_process_id_, render_frame_id); 676} 677 678#if defined(OS_MACOSX) 679void RenderMessageFilter::OnLoadFont(const FontDescriptor& font, 680 IPC::Message* reply_msg) { 681 FontLoader::Result* result = new FontLoader::Result; 682 683 BrowserThread::PostTaskAndReply( 684 BrowserThread::FILE, FROM_HERE, 685 base::Bind(&FontLoader::LoadFont, font, result), 686 base::Bind(&RenderMessageFilter::SendLoadFontReply, this, reply_msg, 687 base::Owned(result))); 688} 689 690void RenderMessageFilter::SendLoadFontReply(IPC::Message* reply, 691 FontLoader::Result* result) { 692 base::SharedMemoryHandle handle; 693 if (result->font_data_size == 0 || result->font_id == 0) { 694 result->font_data_size = 0; 695 result->font_id = 0; 696 handle = base::SharedMemory::NULLHandle(); 697 } else { 698 result->font_data.GiveToProcess(base::GetCurrentProcessHandle(), &handle); 699 } 700 ViewHostMsg_LoadFont::WriteReplyParams( 701 reply, result->font_data_size, handle, result->font_id); 702 Send(reply); 703} 704#endif // OS_MACOSX 705 706#if defined(ENABLE_PLUGINS) 707void RenderMessageFilter::OnGetPlugins( 708 bool refresh, 709 IPC::Message* reply_msg) { 710 // Don't refresh if the specified threshold has not been passed. Note that 711 // this check is performed before off-loading to the file thread. The reason 712 // we do this is that some pages tend to request that the list of plugins be 713 // refreshed at an excessive rate. This instigates disk scanning, as the list 714 // is accumulated by doing multiple reads from disk. This effect is 715 // multiplied when we have several pages requesting this operation. 716 if (refresh) { 717 const base::TimeDelta threshold = base::TimeDelta::FromSeconds( 718 kPluginsRefreshThresholdInSeconds); 719 const base::TimeTicks now = base::TimeTicks::Now(); 720 if (now - last_plugin_refresh_time_ >= threshold) { 721 // Only refresh if the threshold hasn't been exceeded yet. 722 PluginServiceImpl::GetInstance()->RefreshPlugins(); 723 last_plugin_refresh_time_ = now; 724 } 725 } 726 727 PluginServiceImpl::GetInstance()->GetPlugins( 728 base::Bind(&RenderMessageFilter::GetPluginsCallback, this, reply_msg)); 729} 730 731void RenderMessageFilter::GetPluginsCallback( 732 IPC::Message* reply_msg, 733 const std::vector<WebPluginInfo>& all_plugins) { 734 // Filter the plugin list. 735 PluginServiceFilter* filter = PluginServiceImpl::GetInstance()->GetFilter(); 736 std::vector<WebPluginInfo> plugins; 737 738 int child_process_id = -1; 739 int routing_id = MSG_ROUTING_NONE; 740 for (size_t i = 0; i < all_plugins.size(); ++i) { 741 // Copy because the filter can mutate. 742 WebPluginInfo plugin(all_plugins[i]); 743 if (!filter || filter->IsPluginAvailable(child_process_id, 744 routing_id, 745 resource_context_, 746 GURL(), 747 GURL(), 748 &plugin)) { 749 plugins.push_back(plugin); 750 } 751 } 752 753 ViewHostMsg_GetPlugins::WriteReplyParams(reply_msg, plugins); 754 Send(reply_msg); 755} 756 757void RenderMessageFilter::OnGetPluginInfo( 758 int render_frame_id, 759 const GURL& url, 760 const GURL& page_url, 761 const std::string& mime_type, 762 bool* found, 763 WebPluginInfo* info, 764 std::string* actual_mime_type) { 765 bool allow_wildcard = true; 766 *found = plugin_service_->GetPluginInfo( 767 render_process_id_, render_frame_id, resource_context_, 768 url, page_url, mime_type, allow_wildcard, 769 NULL, info, actual_mime_type); 770} 771 772void RenderMessageFilter::OnOpenChannelToPlugin(int render_frame_id, 773 const GURL& url, 774 const GURL& policy_url, 775 const std::string& mime_type, 776 IPC::Message* reply_msg) { 777 OpenChannelToNpapiPluginCallback* client = 778 new OpenChannelToNpapiPluginCallback(this, resource_context_, reply_msg); 779 DCHECK(!ContainsKey(plugin_host_clients_, client)); 780 plugin_host_clients_.insert(client); 781 plugin_service_->OpenChannelToNpapiPlugin( 782 render_process_id_, render_frame_id, 783 url, policy_url, mime_type, client); 784} 785 786void RenderMessageFilter::OnOpenChannelToPepperPlugin( 787 const base::FilePath& path, 788 IPC::Message* reply_msg) { 789 plugin_service_->OpenChannelToPpapiPlugin( 790 render_process_id_, 791 path, 792 profile_data_directory_, 793 new OpenChannelToPpapiPluginCallback(this, resource_context_, reply_msg)); 794} 795 796void RenderMessageFilter::OnDidCreateOutOfProcessPepperInstance( 797 int plugin_child_id, 798 int32 pp_instance, 799 PepperRendererInstanceData instance_data, 800 bool is_external) { 801 // It's important that we supply the render process ID ourselves based on the 802 // channel the message arrived on. We use the 803 // PP_Instance -> (process id, view id) 804 // mapping to decide how to handle messages received from the (untrusted) 805 // plugin, so an exploited renderer must not be able to insert fake mappings 806 // that may allow it access to other render processes. 807 DCHECK_EQ(0, instance_data.render_process_id); 808 instance_data.render_process_id = render_process_id_; 809 if (is_external) { 810 // We provide the BrowserPpapiHost to the embedder, so it's safe to cast. 811 BrowserPpapiHostImpl* host = static_cast<BrowserPpapiHostImpl*>( 812 GetContentClient()->browser()->GetExternalBrowserPpapiHost( 813 plugin_child_id)); 814 if (host) 815 host->AddInstance(pp_instance, instance_data); 816 } else { 817 PpapiPluginProcessHost::DidCreateOutOfProcessInstance( 818 plugin_child_id, pp_instance, instance_data); 819 } 820} 821 822void RenderMessageFilter::OnDidDeleteOutOfProcessPepperInstance( 823 int plugin_child_id, 824 int32 pp_instance, 825 bool is_external) { 826 if (is_external) { 827 // We provide the BrowserPpapiHost to the embedder, so it's safe to cast. 828 BrowserPpapiHostImpl* host = static_cast<BrowserPpapiHostImpl*>( 829 GetContentClient()->browser()->GetExternalBrowserPpapiHost( 830 plugin_child_id)); 831 if (host) 832 host->DeleteInstance(pp_instance); 833 } else { 834 PpapiPluginProcessHost::DidDeleteOutOfProcessInstance( 835 plugin_child_id, pp_instance); 836 } 837} 838 839void RenderMessageFilter::OnOpenChannelToPpapiBroker( 840 int routing_id, 841 const base::FilePath& path) { 842 plugin_service_->OpenChannelToPpapiBroker( 843 render_process_id_, 844 path, 845 new OpenChannelToPpapiBrokerCallback(this, routing_id)); 846} 847#endif // defined(ENABLE_PLUGINS) 848 849void RenderMessageFilter::OnGenerateRoutingID(int* route_id) { 850 *route_id = render_widget_helper_->GetNextRoutingID(); 851} 852 853void RenderMessageFilter::OnGetCPUUsage(int* cpu_usage) { 854 base::TimeTicks now = base::TimeTicks::Now(); 855 int64 since_last_sample_ms = (now - cpu_usage_sample_time_).InMilliseconds(); 856 if (since_last_sample_ms > kCPUUsageSampleIntervalMs) { 857 cpu_usage_sample_time_ = now; 858 cpu_usage_ = static_cast<int>(process_metrics_->GetCPUUsage()); 859 } 860 *cpu_usage = cpu_usage_; 861} 862 863void RenderMessageFilter::OnGetAudioHardwareConfig( 864 media::AudioParameters* input_params, 865 media::AudioParameters* output_params) { 866 DCHECK(input_params); 867 DCHECK(output_params); 868 *output_params = audio_manager_->GetDefaultOutputStreamParameters(); 869 870 // TODO(henrika): add support for all available input devices. 871 *input_params = audio_manager_->GetInputStreamParameters( 872 media::AudioManagerBase::kDefaultDeviceId); 873} 874 875#if defined(OS_WIN) 876void RenderMessageFilter::OnGetMonitorColorProfile(std::vector<char>* profile) { 877 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO)); 878 *profile = g_color_profile.Get().profile(); 879} 880#endif 881 882void RenderMessageFilter::OnDownloadUrl(int render_view_id, 883 const GURL& url, 884 const Referrer& referrer, 885 const base::string16& suggested_name, 886 const bool use_prompt) { 887 scoped_ptr<DownloadSaveInfo> save_info(new DownloadSaveInfo()); 888 save_info->suggested_name = suggested_name; 889 save_info->prompt_for_save_location = use_prompt; 890 891 // There may be a special cookie store that we could use for this download, 892 // rather than the default one. Since this feature is generally only used for 893 // proper render views, and not downloads, we do not need to retrieve the 894 // special cookie store here, but just initialize the request to use the 895 // default cookie store. 896 // TODO(tburkard): retrieve the appropriate special cookie store, if this 897 // is ever to be used for downloads as well. 898 scoped_ptr<net::URLRequest> request( 899 resource_context_->GetRequestContext()->CreateRequest( 900 url, net::DEFAULT_PRIORITY, NULL, NULL)); 901 RecordDownloadSource(INITIATED_BY_RENDERER); 902 resource_dispatcher_host_->BeginDownload( 903 request.Pass(), 904 referrer, 905 true, // is_content_initiated 906 resource_context_, 907 render_process_id_, 908 render_view_id, 909 false, 910 save_info.Pass(), 911 content::DownloadItem::kInvalidId, 912 ResourceDispatcherHostImpl::DownloadStartedCallback()); 913} 914 915void RenderMessageFilter::OnCheckNotificationPermission( 916 const GURL& source_origin, int* result) { 917#if defined(ENABLE_NOTIFICATIONS) 918 *result = GetContentClient()->browser()-> 919 CheckDesktopNotificationPermission(source_origin, resource_context_, 920 render_process_id_); 921#else 922 *result = blink::WebNotificationPresenter::PermissionAllowed; 923#endif 924} 925 926void RenderMessageFilter::OnAllocateSharedMemory( 927 uint32 buffer_size, 928 base::SharedMemoryHandle* handle) { 929 ChildProcessHostImpl::AllocateSharedMemory( 930 buffer_size, PeerHandle(), handle); 931} 932 933void RenderMessageFilter::OnAllocateSharedBitmap( 934 uint32 buffer_size, 935 const cc::SharedBitmapId& id, 936 base::SharedMemoryHandle* handle) { 937 HostSharedBitmapManager::current()->AllocateSharedBitmapForChild( 938 PeerHandle(), buffer_size, id, handle); 939} 940 941void RenderMessageFilter::OnAllocatedSharedBitmap( 942 size_t buffer_size, 943 const base::SharedMemoryHandle& handle, 944 const cc::SharedBitmapId& id) { 945 HostSharedBitmapManager::current()->ChildAllocatedSharedBitmap( 946 buffer_size, handle, PeerHandle(), id); 947} 948 949void RenderMessageFilter::OnDeletedSharedBitmap(const cc::SharedBitmapId& id) { 950 HostSharedBitmapManager::current()->ChildDeletedSharedBitmap(id); 951} 952 953net::CookieStore* RenderMessageFilter::GetCookieStoreForURL( 954 const GURL& url) { 955 DCHECK_CURRENTLY_ON(BrowserThread::IO); 956 957 net::URLRequestContext* context = 958 GetContentClient()->browser()->OverrideRequestContextForURL( 959 url, resource_context_); 960 961 // If we should use a special URLRequestContext rather than the default one, 962 // return the cookie store of that special URLRequestContext. 963 if (context) 964 return context->cookie_store(); 965 966 // Otherwise, if there is a special cookie store to be used for this process, 967 // return that cookie store. 968 net::CookieStore* cookie_store = 969 GetContentClient()->browser()->OverrideCookieStoreForRenderProcess( 970 render_process_id_); 971 if (cookie_store) 972 return cookie_store; 973 974 // Otherwise, return the cookie store of the default request context used 975 // for this renderer. 976 return request_context_->GetURLRequestContext()->cookie_store(); 977} 978 979#if defined(OS_POSIX) && !defined(OS_ANDROID) 980void RenderMessageFilter::OnAllocTransportDIB( 981 uint32 size, bool cache_in_browser, TransportDIB::Handle* handle) { 982 render_widget_helper_->AllocTransportDIB(size, cache_in_browser, handle); 983} 984 985void RenderMessageFilter::OnFreeTransportDIB( 986 TransportDIB::Id dib_id) { 987 render_widget_helper_->FreeTransportDIB(dib_id); 988} 989#endif 990 991bool RenderMessageFilter::CheckPreparsedJsCachingEnabled() const { 992 static bool checked = false; 993 static bool result = false; 994 if (!checked) { 995 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 996 result = command_line.HasSwitch(switches::kEnablePreparsedJsCaching); 997 checked = true; 998 } 999 return result; 1000} 1001 1002void RenderMessageFilter::OnCacheableMetadataAvailable( 1003 const GURL& url, 1004 double expected_response_time, 1005 const std::vector<char>& data) { 1006 if (!CheckPreparsedJsCachingEnabled()) 1007 return; 1008 1009 net::HttpCache* cache = request_context_->GetURLRequestContext()-> 1010 http_transaction_factory()->GetCache(); 1011 DCHECK(cache); 1012 1013 // Use the same priority for the metadata write as for script 1014 // resources (see defaultPriorityForResourceType() in WebKit's 1015 // CachedResource.cpp). Note that WebURLRequest::PriorityMedium 1016 // corresponds to net::LOW (see ConvertWebKitPriorityToNetPriority() 1017 // in weburlloader_impl.cc). 1018 const net::RequestPriority kPriority = net::LOW; 1019 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(data.size())); 1020 memcpy(buf->data(), &data.front(), data.size()); 1021 cache->WriteMetadata(url, 1022 kPriority, 1023 base::Time::FromDoubleT(expected_response_time), 1024 buf.get(), 1025 data.size()); 1026} 1027 1028void RenderMessageFilter::OnKeygen(uint32 key_size_index, 1029 const std::string& challenge_string, 1030 const GURL& url, 1031 IPC::Message* reply_msg) { 1032 // Map displayed strings indicating level of keysecurity in the <keygen> 1033 // menu to the key size in bits. (See SSLKeyGeneratorChromium.cpp in WebCore.) 1034 int key_size_in_bits; 1035 switch (key_size_index) { 1036 case 0: 1037 key_size_in_bits = 2048; 1038 break; 1039 case 1: 1040 key_size_in_bits = 1024; 1041 break; 1042 default: 1043 DCHECK(false) << "Illegal key_size_index " << key_size_index; 1044 ViewHostMsg_Keygen::WriteReplyParams(reply_msg, std::string()); 1045 Send(reply_msg); 1046 return; 1047 } 1048 1049 resource_context_->CreateKeygenHandler( 1050 key_size_in_bits, 1051 challenge_string, 1052 url, 1053 base::Bind( 1054 &RenderMessageFilter::PostKeygenToWorkerThread, this, reply_msg)); 1055} 1056 1057void RenderMessageFilter::PostKeygenToWorkerThread( 1058 IPC::Message* reply_msg, 1059 scoped_ptr<net::KeygenHandler> keygen_handler) { 1060 VLOG(1) << "Dispatching keygen task to worker pool."; 1061 // Dispatch to worker pool, so we do not block the IO thread. 1062 if (!base::WorkerPool::PostTask( 1063 FROM_HERE, 1064 base::Bind(&RenderMessageFilter::OnKeygenOnWorkerThread, 1065 this, 1066 base::Passed(&keygen_handler), 1067 reply_msg), 1068 true)) { 1069 NOTREACHED() << "Failed to dispatch keygen task to worker pool"; 1070 ViewHostMsg_Keygen::WriteReplyParams(reply_msg, std::string()); 1071 Send(reply_msg); 1072 } 1073} 1074 1075void RenderMessageFilter::OnKeygenOnWorkerThread( 1076 scoped_ptr<net::KeygenHandler> keygen_handler, 1077 IPC::Message* reply_msg) { 1078 DCHECK(reply_msg); 1079 1080 // Generate a signed public key and challenge, then send it back. 1081 ViewHostMsg_Keygen::WriteReplyParams( 1082 reply_msg, 1083 keygen_handler->GenKeyAndSignChallenge()); 1084 Send(reply_msg); 1085} 1086 1087void RenderMessageFilter::OnMediaLogEvents( 1088 const std::vector<media::MediaLogEvent>& events) { 1089 if (media_internals_) 1090 media_internals_->OnMediaEvents(render_process_id_, events); 1091} 1092 1093void RenderMessageFilter::CheckPolicyForCookies( 1094 int render_frame_id, 1095 const GURL& url, 1096 const GURL& first_party_for_cookies, 1097 IPC::Message* reply_msg, 1098 const net::CookieList& cookie_list) { 1099 net::CookieStore* cookie_store = GetCookieStoreForURL(url); 1100 // Check the policy for get cookies, and pass cookie_list to the 1101 // TabSpecificContentSetting for logging purpose. 1102 if (GetContentClient()->browser()->AllowGetCookie( 1103 url, first_party_for_cookies, cookie_list, resource_context_, 1104 render_process_id_, render_frame_id)) { 1105 // Gets the cookies from cookie store if allowed. 1106 cookie_store->GetCookiesWithOptionsAsync( 1107 url, net::CookieOptions(), 1108 base::Bind(&RenderMessageFilter::SendGetCookiesResponse, 1109 this, reply_msg)); 1110 } else { 1111 SendGetCookiesResponse(reply_msg, std::string()); 1112 } 1113} 1114 1115void RenderMessageFilter::SendGetCookiesResponse(IPC::Message* reply_msg, 1116 const std::string& cookies) { 1117 ViewHostMsg_GetCookies::WriteReplyParams(reply_msg, cookies); 1118 Send(reply_msg); 1119} 1120 1121void RenderMessageFilter::SendGetRawCookiesResponse( 1122 IPC::Message* reply_msg, 1123 const net::CookieList& cookie_list) { 1124 std::vector<CookieData> cookies; 1125 for (size_t i = 0; i < cookie_list.size(); ++i) 1126 cookies.push_back(CookieData(cookie_list[i])); 1127 ViewHostMsg_GetRawCookies::WriteReplyParams(reply_msg, cookies); 1128 Send(reply_msg); 1129} 1130 1131void RenderMessageFilter::OnCompletedOpenChannelToNpapiPlugin( 1132 OpenChannelToNpapiPluginCallback* client) { 1133 DCHECK_CURRENTLY_ON(BrowserThread::IO); 1134 DCHECK(ContainsKey(plugin_host_clients_, client)); 1135 plugin_host_clients_.erase(client); 1136} 1137 1138void RenderMessageFilter::OnAre3DAPIsBlocked(int render_view_id, 1139 const GURL& top_origin_url, 1140 ThreeDAPIType requester, 1141 bool* blocked) { 1142 *blocked = GpuDataManagerImpl::GetInstance()->Are3DAPIsBlocked( 1143 top_origin_url, render_process_id_, render_view_id, requester); 1144} 1145 1146void RenderMessageFilter::OnDidLose3DContext( 1147 const GURL& top_origin_url, 1148 ThreeDAPIType /* unused */, 1149 int arb_robustness_status_code) { 1150#if defined(OS_MACOSX) 1151 // TODO(kbr): this file indirectly includes npapi.h, which on Mac 1152 // OS pulls in the system OpenGL headers. For some 1153 // not-yet-investigated reason this breaks the build with the 10.6 1154 // SDK but not 10.7. For now work around this in a way compatible 1155 // with the Khronos headers. 1156#ifndef GL_GUILTY_CONTEXT_RESET_ARB 1157#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253 1158#endif 1159#ifndef GL_INNOCENT_CONTEXT_RESET_ARB 1160#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254 1161#endif 1162#ifndef GL_UNKNOWN_CONTEXT_RESET_ARB 1163#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255 1164#endif 1165 1166#endif 1167 GpuDataManagerImpl::DomainGuilt guilt; 1168 switch (arb_robustness_status_code) { 1169 case GL_GUILTY_CONTEXT_RESET_ARB: 1170 guilt = GpuDataManagerImpl::DOMAIN_GUILT_KNOWN; 1171 break; 1172 case GL_UNKNOWN_CONTEXT_RESET_ARB: 1173 guilt = GpuDataManagerImpl::DOMAIN_GUILT_UNKNOWN; 1174 break; 1175 default: 1176 // Ignore lost contexts known to be innocent. 1177 return; 1178 } 1179 1180 GpuDataManagerImpl::GetInstance()->BlockDomainFrom3DAPIs( 1181 top_origin_url, guilt); 1182} 1183 1184#if defined(OS_WIN) 1185void RenderMessageFilter::OnPreCacheFontCharacters(const LOGFONT& font, 1186 const base::string16& str) { 1187 // TODO(scottmg): Move this to FontCacheDispatcher, http://crbug.com/356346. 1188 if (!ShouldUseDirectWrite()) 1189 return; 1190 // First, comments from FontCacheDispatcher::OnPreCacheFont do apply here too. 1191 // Except that for True Type fonts, 1192 // GetTextMetrics will not load the font in memory. 1193 // The only way windows seem to load properly, it is to create a similar 1194 // device (like the one in which we print), then do an ExtTextOut, 1195 // as we do in the printing thread, which is sandboxed. 1196 HDC hdc = CreateEnhMetaFile(NULL, NULL, NULL, NULL); 1197 HFONT font_handle = CreateFontIndirect(&font); 1198 DCHECK(NULL != font_handle); 1199 1200 HGDIOBJ old_font = SelectObject(hdc, font_handle); 1201 DCHECK(NULL != old_font); 1202 1203 ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, str.c_str(), str.length(), NULL); 1204 1205 SelectObject(hdc, old_font); 1206 DeleteObject(font_handle); 1207 1208 HENHMETAFILE metafile = CloseEnhMetaFile(hdc); 1209 1210 if (metafile) { 1211 DeleteEnhMetaFile(metafile); 1212 } 1213} 1214#endif 1215 1216#if defined(OS_ANDROID) 1217void RenderMessageFilter::OnWebAudioMediaCodec( 1218 base::SharedMemoryHandle encoded_data_handle, 1219 base::FileDescriptor pcm_output, 1220 uint32_t data_size) { 1221 // Let a WorkerPool handle this request since the WebAudio 1222 // MediaCodec bridge is slow and can block while sending the data to 1223 // the renderer. 1224 base::WorkerPool::PostTask( 1225 FROM_HERE, 1226 base::Bind(&media::WebAudioMediaCodecBridge::RunWebAudioMediaCodec, 1227 encoded_data_handle, pcm_output, data_size), 1228 true); 1229} 1230#endif 1231 1232void RenderMessageFilter::OnAllocateGpuMemoryBuffer(uint32 width, 1233 uint32 height, 1234 uint32 internalformat, 1235 uint32 usage, 1236 IPC::Message* reply) { 1237 if (!GpuMemoryBufferImpl::IsFormatValid(internalformat) || 1238 !GpuMemoryBufferImpl::IsUsageValid(usage)) { 1239 GpuMemoryBufferAllocated(reply, gfx::GpuMemoryBufferHandle()); 1240 return; 1241 } 1242 base::CheckedNumeric<int> size = width; 1243 size *= height; 1244 if (!size.IsValid()) { 1245 GpuMemoryBufferAllocated(reply, gfx::GpuMemoryBufferHandle()); 1246 return; 1247 } 1248 1249#if defined(OS_MACOSX) 1250 // TODO(reveman): This should be moved to 1251 // GpuMemoryBufferImpl::AllocateForChildProcess and 1252 // GpuMemoryBufferImplIOSurface. crbug.com/325045, crbug.com/323304 1253 if (GpuMemoryBufferImplIOSurface::IsConfigurationSupported(internalformat, 1254 usage)) { 1255 IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize(); 1256 if (io_surface_support) { 1257 base::ScopedCFTypeRef<CFMutableDictionaryRef> properties; 1258 properties.reset( 1259 CFDictionaryCreateMutable(kCFAllocatorDefault, 1260 0, 1261 &kCFTypeDictionaryKeyCallBacks, 1262 &kCFTypeDictionaryValueCallBacks)); 1263 AddIntegerValue(properties, 1264 io_surface_support->GetKIOSurfaceWidth(), 1265 width); 1266 AddIntegerValue(properties, 1267 io_surface_support->GetKIOSurfaceHeight(), 1268 height); 1269 AddIntegerValue(properties, 1270 io_surface_support->GetKIOSurfaceBytesPerElement(), 1271 GpuMemoryBufferImpl::BytesPerPixel(internalformat)); 1272 AddIntegerValue(properties, 1273 io_surface_support->GetKIOSurfacePixelFormat(), 1274 GpuMemoryBufferImplIOSurface::PixelFormat( 1275 internalformat)); 1276 // TODO(reveman): Remove this when using a mach_port_t to transfer 1277 // IOSurface to renderer process. crbug.com/323304 1278 AddBooleanValue(properties, 1279 io_surface_support->GetKIOSurfaceIsGlobal(), 1280 true); 1281 1282 base::ScopedCFTypeRef<CFTypeRef> io_surface( 1283 io_surface_support->IOSurfaceCreate(properties)); 1284 if (io_surface) { 1285 gfx::GpuMemoryBufferHandle handle; 1286 handle.type = gfx::IO_SURFACE_BUFFER; 1287 handle.io_surface_id = io_surface_support->IOSurfaceGetID(io_surface); 1288 1289 // TODO(reveman): This makes the assumption that the renderer will 1290 // grab a reference to the surface before sending another message. 1291 // crbug.com/325045 1292 last_io_surface_ = io_surface; 1293 GpuMemoryBufferAllocated(reply, handle); 1294 return; 1295 } 1296 } 1297 } 1298#endif 1299 1300#if defined(OS_ANDROID) 1301 // TODO(reveman): This should be moved to 1302 // GpuMemoryBufferImpl::AllocateForChildProcess and 1303 // GpuMemoryBufferImplSurfaceTexture when adding support for out-of-process 1304 // GPU service. crbug.com/368716 1305 if (GpuMemoryBufferImplSurfaceTexture::IsConfigurationSupported( 1306 internalformat, usage)) { 1307 // Each surface texture is associated with a render process id. This allows 1308 // the GPU service and Java Binder IPC to verify that a renderer is not 1309 // trying to use a surface texture it doesn't own. 1310 int surface_texture_id = 1311 CompositorImpl::CreateSurfaceTexture(render_process_id_); 1312 if (surface_texture_id != -1) { 1313 gfx::GpuMemoryBufferHandle handle; 1314 handle.type = gfx::SURFACE_TEXTURE_BUFFER; 1315 handle.surface_texture_id = 1316 gfx::SurfaceTextureId(surface_texture_id, render_process_id_); 1317 GpuMemoryBufferAllocated(reply, handle); 1318 return; 1319 } 1320 } 1321#endif 1322 1323 GpuMemoryBufferImpl::AllocateForChildProcess( 1324 gfx::Size(width, height), 1325 internalformat, 1326 usage, 1327 PeerHandle(), 1328 base::Bind(&RenderMessageFilter::GpuMemoryBufferAllocated, this, reply)); 1329} 1330 1331void RenderMessageFilter::GpuMemoryBufferAllocated( 1332 IPC::Message* reply, 1333 const gfx::GpuMemoryBufferHandle& handle) { 1334 ChildProcessHostMsg_SyncAllocateGpuMemoryBuffer::WriteReplyParams(reply, 1335 handle); 1336 Send(reply); 1337} 1338 1339} // namespace content 1340