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