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