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