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