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