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