blob: e4cb17c082ab899a31946630e9040a7390d6e740 [file] [log] [blame]
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001// 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"
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010013#include "base/strings/sys_string_conversions.h"
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010014#include "base/strings/utf_string_conversions.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000015#include "base/threading/thread.h"
16#include "base/threading/worker_pool.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000017#include "content/browser/browser_main_loop.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000018#include "content/browser/child_process_security_policy_impl.h"
Ben Murdochbb1529c2013-08-08 10:24:53 +010019#include "content/browser/dom_storage/dom_storage_context_wrapper.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000020#include "content/browser/dom_storage/session_storage_namespace_impl.h"
21#include "content/browser/download/download_stats.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000022#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"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000025#include "content/browser/plugin_process_host.h"
26#include "content/browser/plugin_service_impl.h"
27#include "content/browser/ppapi_plugin_process_host.h"
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +010028#include "content/browser/renderer_host/pepper/pepper_security_helper.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000029#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"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000032#include "content/common/child_process_host_impl.h"
33#include "content/common/child_process_messages.h"
Ben Murdocheb525c52013-07-10 11:40:50 +010034#include "content/common/cookie_data.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000035#include "content/common/desktop_notification_messages.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000036#include "content/common/media/media_param_traits.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000037#include "content/common/view_messages.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000038#include "content/public/browser/browser_child_process_host.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000039#include "content/public/browser/browser_context.h"
40#include "content/public/browser/browser_thread.h"
41#include "content/public/browser/content_browser_client.h"
42#include "content/public/browser/download_save_info.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000043#include "content/public/browser/plugin_service_filter.h"
44#include "content/public/browser/resource_context.h"
45#include "content/public/browser/user_metrics.h"
46#include "content/public/common/content_switches.h"
47#include "content/public/common/context_menu_params.h"
48#include "content/public/common/url_constants.h"
Ben Murdochca12bfa2013-07-23 11:17:05 +010049#include "content/public/common/webplugininfo.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000050#include "ipc/ipc_channel_handle.h"
51#include "ipc/ipc_platform_file.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000052#include "media/audio/audio_manager.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000053#include "media/audio/audio_manager_base.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000054#include "media/audio/audio_parameters.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000055#include "media/base/media_log_event.h"
56#include "net/base/io_buffer.h"
57#include "net/base/keygen_handler.h"
58#include "net/base/mime_util.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000059#include "net/base/request_priority.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000060#include "net/cookies/canonical_cookie.h"
61#include "net/cookies/cookie_monster.h"
62#include "net/http/http_cache.h"
63#include "net/url_request/url_request_context.h"
64#include "net/url_request/url_request_context_getter.h"
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +010065#include "ppapi/shared_impl/file_type_conversion.h"
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +010066#include "third_party/WebKit/public/web/WebNotificationPresenter.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000067#include "ui/gfx/color_profile.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000068#include "webkit/plugins/plugin_constants.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000069
70#if defined(OS_MACOSX)
71#include "content/common/mac/font_descriptor.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000072#else
73#include "gpu/GLES2/gl2extchromium.h"
74#include "third_party/khronos/GLES2/gl2.h"
75#include "third_party/khronos/GLES2/gl2ext.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000076#endif
77#if defined(OS_POSIX)
78#include "base/file_descriptor_posix.h"
79#endif
80#if defined(OS_WIN)
81#include "content/browser/renderer_host/backing_store_win.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000082#include "content/common/font_cache_dispatcher_win.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000083#endif
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010084#if defined(OS_ANDROID)
85#include "media/base/android/webaudio_media_codec_bridge.h"
86#endif
Torne (Richard Coles)58218062012-11-14 11:43:16 +000087
88using net::CookieStore;
89
90namespace content {
91namespace {
92
93const int kPluginsRefreshThresholdInSeconds = 3;
94
95// When two CPU usage queries arrive within this interval, we sample the CPU
96// usage only once and send it as a response for both queries.
97static const int64 kCPUUsageSampleIntervalMs = 900;
98
99// On Windows, |g_color_profile| can run on an arbitrary background thread.
100// We avoid races by using LazyInstance's constructor lock to initialize the
101// object.
102base::LazyInstance<gfx::ColorProfile>::Leaky g_color_profile =
103 LAZY_INSTANCE_INITIALIZER;
104
105// Common functionality for converting a sync renderer message to a callback
106// function in the browser. Derive from this, create it on the heap when
107// issuing your callback. When done, write your reply parameters into
108// reply_msg(), and then call SendReplyAndDeleteThis().
109class RenderMessageCompletionCallback {
110 public:
111 RenderMessageCompletionCallback(RenderMessageFilter* filter,
112 IPC::Message* reply_msg)
113 : filter_(filter),
114 reply_msg_(reply_msg) {
115 }
116
117 virtual ~RenderMessageCompletionCallback() {
118 }
119
120 RenderMessageFilter* filter() { return filter_.get(); }
121 IPC::Message* reply_msg() { return reply_msg_; }
122
123 void SendReplyAndDeleteThis() {
124 filter_->Send(reply_msg_);
125 delete this;
126 }
127
128 private:
129 scoped_refptr<RenderMessageFilter> filter_;
130 IPC::Message* reply_msg_;
131};
132
133class OpenChannelToPpapiPluginCallback
134 : public RenderMessageCompletionCallback,
135 public PpapiPluginProcessHost::PluginClient {
136 public:
137 OpenChannelToPpapiPluginCallback(RenderMessageFilter* filter,
138 ResourceContext* context,
139 IPC::Message* reply_msg)
140 : RenderMessageCompletionCallback(filter, reply_msg),
141 context_(context) {
142 }
143
144 virtual void GetPpapiChannelInfo(base::ProcessHandle* renderer_handle,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000145 int* renderer_id) OVERRIDE {
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100146 *renderer_handle = filter()->PeerHandle();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000147 *renderer_id = filter()->render_process_id();
148 }
149
150 virtual void OnPpapiChannelOpened(const IPC::ChannelHandle& channel_handle,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000151 base::ProcessId plugin_pid,
152 int plugin_child_id) OVERRIDE {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000153 ViewHostMsg_OpenChannelToPepperPlugin::WriteReplyParams(
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000154 reply_msg(), channel_handle, plugin_pid, plugin_child_id);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000155 SendReplyAndDeleteThis();
156 }
157
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000158 virtual bool OffTheRecord() OVERRIDE {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000159 return filter()->OffTheRecord();
160 }
161
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000162 virtual ResourceContext* GetResourceContext() OVERRIDE {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000163 return context_;
164 }
165
166 private:
167 ResourceContext* context_;
168};
169
170class OpenChannelToPpapiBrokerCallback
171 : public PpapiPluginProcessHost::BrokerClient {
172 public:
173 OpenChannelToPpapiBrokerCallback(RenderMessageFilter* filter,
Ben Murdoch32409262013-08-07 11:04:47 +0100174 int routing_id)
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000175 : filter_(filter),
Ben Murdoch32409262013-08-07 11:04:47 +0100176 routing_id_(routing_id) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000177 }
178
179 virtual ~OpenChannelToPpapiBrokerCallback() {}
180
181 virtual void GetPpapiChannelInfo(base::ProcessHandle* renderer_handle,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000182 int* renderer_id) OVERRIDE {
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100183 *renderer_handle = filter_->PeerHandle();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000184 *renderer_id = filter_->render_process_id();
185 }
186
187 virtual void OnPpapiChannelOpened(const IPC::ChannelHandle& channel_handle,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000188 base::ProcessId plugin_pid,
189 int /* plugin_child_id */) OVERRIDE {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000190 filter_->Send(new ViewMsg_PpapiBrokerChannelCreated(routing_id_,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000191 plugin_pid,
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000192 channel_handle));
193 delete this;
194 }
195
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000196 virtual bool OffTheRecord() OVERRIDE {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000197 return filter_->OffTheRecord();
198 }
199
200 private:
201 scoped_refptr<RenderMessageFilter> filter_;
202 int routing_id_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000203};
204
205} // namespace
206
207class RenderMessageFilter::OpenChannelToNpapiPluginCallback
208 : public RenderMessageCompletionCallback,
209 public PluginProcessHost::Client {
210 public:
211 OpenChannelToNpapiPluginCallback(RenderMessageFilter* filter,
212 ResourceContext* context,
213 IPC::Message* reply_msg)
214 : RenderMessageCompletionCallback(filter, reply_msg),
215 context_(context),
216 host_(NULL),
217 sent_plugin_channel_request_(false) {
218 }
219
220 virtual int ID() OVERRIDE {
221 return filter()->render_process_id();
222 }
223
224 virtual ResourceContext* GetResourceContext() OVERRIDE {
225 return context_;
226 }
227
228 virtual bool OffTheRecord() OVERRIDE {
229 if (filter()->OffTheRecord())
230 return true;
231 if (GetContentClient()->browser()->AllowSaveLocalState(context_))
232 return false;
233
234 // For now, only disallow storing data for Flash <http://crbug.com/97319>.
235 for (size_t i = 0; i < info_.mime_types.size(); ++i) {
236 if (info_.mime_types[i].mime_type == kFlashPluginSwfMimeType)
237 return true;
238 }
239 return false;
240 }
241
Ben Murdochca12bfa2013-07-23 11:17:05 +0100242 virtual void SetPluginInfo(const WebPluginInfo& info) OVERRIDE {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000243 info_ = info;
244 }
245
246 virtual void OnFoundPluginProcessHost(PluginProcessHost* host) OVERRIDE {
247 DCHECK(host);
248 host_ = host;
249 }
250
251 virtual void OnSentPluginChannelRequest() OVERRIDE {
252 sent_plugin_channel_request_ = true;
253 }
254
255 virtual void OnChannelOpened(const IPC::ChannelHandle& handle) OVERRIDE {
256 WriteReplyAndDeleteThis(handle);
257 }
258
259 virtual void OnError() OVERRIDE {
260 WriteReplyAndDeleteThis(IPC::ChannelHandle());
261 }
262
263 PluginProcessHost* host() const {
264 return host_;
265 }
266
267 bool sent_plugin_channel_request() const {
268 return sent_plugin_channel_request_;
269 }
270
271 void Cancel() {
272 delete this;
273 }
274
275 private:
276 void WriteReplyAndDeleteThis(const IPC::ChannelHandle& handle) {
277 ViewHostMsg_OpenChannelToPlugin::WriteReplyParams(reply_msg(),
278 handle, info_);
279 filter()->OnCompletedOpenChannelToNpapiPlugin(this);
280 SendReplyAndDeleteThis();
281 }
282
283 ResourceContext* context_;
Ben Murdochca12bfa2013-07-23 11:17:05 +0100284 WebPluginInfo info_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000285 PluginProcessHost* host_;
286 bool sent_plugin_channel_request_;
287};
288
289RenderMessageFilter::RenderMessageFilter(
290 int render_process_id,
Ben Murdoch558790d2013-07-30 15:19:42 +0100291 bool is_guest,
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000292 PluginServiceImpl* plugin_service,
293 BrowserContext* browser_context,
294 net::URLRequestContextGetter* request_context,
295 RenderWidgetHelper* render_widget_helper,
Ben Murdocheb525c52013-07-10 11:40:50 +0100296 media::AudioManager* audio_manager,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000297 MediaInternals* media_internals,
Ben Murdochbb1529c2013-08-08 10:24:53 +0100298 DOMStorageContextWrapper* dom_storage_context)
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000299 : resource_dispatcher_host_(ResourceDispatcherHostImpl::Get()),
300 plugin_service_(plugin_service),
301 profile_data_directory_(browser_context->GetPath()),
302 request_context_(request_context),
303 resource_context_(browser_context->GetResourceContext()),
304 render_widget_helper_(render_widget_helper),
305 incognito_(browser_context->IsOffTheRecord()),
306 dom_storage_context_(dom_storage_context),
307 render_process_id_(render_process_id),
Ben Murdoch558790d2013-07-30 15:19:42 +0100308 is_guest_(is_guest),
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000309 cpu_usage_(0),
Ben Murdocheb525c52013-07-10 11:40:50 +0100310 audio_manager_(audio_manager),
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000311 media_internals_(media_internals) {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100312 DCHECK(request_context_.get());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000313
314 render_widget_helper_->Init(render_process_id_, resource_dispatcher_host_);
315}
316
317RenderMessageFilter::~RenderMessageFilter() {
318 // This function should be called on the IO thread.
319 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
320 DCHECK(plugin_host_clients_.empty());
321}
322
323void RenderMessageFilter::OnChannelClosing() {
324 BrowserMessageFilter::OnChannelClosing();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000325#if defined(ENABLE_PLUGINS)
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000326 for (std::set<OpenChannelToNpapiPluginCallback*>::iterator it =
327 plugin_host_clients_.begin(); it != plugin_host_clients_.end(); ++it) {
328 OpenChannelToNpapiPluginCallback* client = *it;
329 if (client->host()) {
330 if (client->sent_plugin_channel_request()) {
331 client->host()->CancelSentRequest(client);
332 } else {
333 client->host()->CancelPendingRequest(client);
334 }
335 } else {
336 plugin_service_->CancelOpenChannelToNpapiPlugin(client);
337 }
338 client->Cancel();
339 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000340#endif // defined(ENABLE_PLUGINS)
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000341 plugin_host_clients_.clear();
342}
343
344void RenderMessageFilter::OnChannelConnected(int32 peer_id) {
345 BrowserMessageFilter::OnChannelConnected(peer_id);
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100346 base::ProcessHandle handle = PeerHandle();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000347#if defined(OS_MACOSX)
348 process_metrics_.reset(base::ProcessMetrics::CreateProcessMetrics(handle,
349 NULL));
350#else
351 process_metrics_.reset(base::ProcessMetrics::CreateProcessMetrics(handle));
352#endif
353 cpu_usage_ = process_metrics_->GetCPUUsage(); // Initialize CPU usage counters
354 cpu_usage_sample_time_ = base::TimeTicks::Now();
355}
356
357bool RenderMessageFilter::OnMessageReceived(const IPC::Message& message,
358 bool* message_was_ok) {
359 bool handled = true;
360 IPC_BEGIN_MESSAGE_MAP_EX(RenderMessageFilter, message, *message_was_ok)
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000361#if defined(OS_WIN)
362 IPC_MESSAGE_HANDLER(ViewHostMsg_PreCacheFontCharacters,
363 OnPreCacheFontCharacters)
364#endif
365 IPC_MESSAGE_HANDLER(ViewHostMsg_GetProcessMemorySizes,
366 OnGetProcessMemorySizes)
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000367 IPC_MESSAGE_HANDLER(ViewHostMsg_GenerateRoutingID, OnGenerateRoutingID)
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000368 IPC_MESSAGE_HANDLER(ViewHostMsg_CreateWindow, OnCreateWindow)
369 IPC_MESSAGE_HANDLER(ViewHostMsg_CreateWidget, OnCreateWidget)
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000370 IPC_MESSAGE_HANDLER(ViewHostMsg_CreateFullscreenWidget,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000371 OnCreateFullscreenWidget)
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000372 IPC_MESSAGE_HANDLER(ViewHostMsg_SetCookie, OnSetCookie)
373 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_GetCookies, OnGetCookies)
374 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_GetRawCookies, OnGetRawCookies)
375 IPC_MESSAGE_HANDLER(ViewHostMsg_DeleteCookie, OnDeleteCookie)
376 IPC_MESSAGE_HANDLER(ViewHostMsg_CookiesEnabled, OnCookiesEnabled)
377#if defined(OS_MACOSX)
378 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_LoadFont, OnLoadFont)
379#endif
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000380 IPC_MESSAGE_HANDLER(ViewHostMsg_DownloadUrl, OnDownloadUrl)
381#if defined(ENABLE_PLUGINS)
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000382 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_GetPlugins, OnGetPlugins)
383 IPC_MESSAGE_HANDLER(ViewHostMsg_GetPluginInfo, OnGetPluginInfo)
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000384 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_OpenChannelToPlugin,
385 OnOpenChannelToPlugin)
386 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_OpenChannelToPepperPlugin,
387 OnOpenChannelToPepperPlugin)
388 IPC_MESSAGE_HANDLER(ViewHostMsg_DidCreateOutOfProcessPepperInstance,
389 OnDidCreateOutOfProcessPepperInstance)
390 IPC_MESSAGE_HANDLER(ViewHostMsg_DidDeleteOutOfProcessPepperInstance,
391 OnDidDeleteOutOfProcessPepperInstance)
392 IPC_MESSAGE_HANDLER(ViewHostMsg_OpenChannelToPpapiBroker,
393 OnOpenChannelToPpapiBroker)
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100394 IPC_MESSAGE_HANDLER(ViewHostMsg_AsyncOpenPepperFile, OnAsyncOpenPepperFile)
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000395#endif
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000396 IPC_MESSAGE_HANDLER_GENERIC(ViewHostMsg_UpdateRect,
397 render_widget_helper_->DidReceiveBackingStoreMsg(message))
398 IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateIsDelayed, OnUpdateIsDelayed)
399 IPC_MESSAGE_HANDLER(DesktopNotificationHostMsg_CheckPermission,
400 OnCheckNotificationPermission)
401 IPC_MESSAGE_HANDLER(ChildProcessHostMsg_SyncAllocateSharedMemory,
402 OnAllocateSharedMemory)
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100403#if defined(OS_POSIX) && !defined(TOOLKIT_GTK) && !defined(OS_ANDROID)
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000404 IPC_MESSAGE_HANDLER(ViewHostMsg_AllocTransportDIB, OnAllocTransportDIB)
405 IPC_MESSAGE_HANDLER(ViewHostMsg_FreeTransportDIB, OnFreeTransportDIB)
406#endif
407 IPC_MESSAGE_HANDLER(ViewHostMsg_DidGenerateCacheableMetadata,
408 OnCacheableMetadataAvailable)
409 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_Keygen, OnKeygen)
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000410 IPC_MESSAGE_HANDLER(ViewHostMsg_GetCPUUsage, OnGetCPUUsage)
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000411 IPC_MESSAGE_HANDLER(ViewHostMsg_GetAudioHardwareConfig,
412 OnGetAudioHardwareConfig)
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000413 IPC_MESSAGE_HANDLER(ViewHostMsg_GetMonitorColorProfile,
414 OnGetMonitorColorProfile)
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100415 IPC_MESSAGE_HANDLER(ViewHostMsg_MediaLogEvents, OnMediaLogEvents)
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000416 IPC_MESSAGE_HANDLER(ViewHostMsg_Are3DAPIsBlocked, OnAre3DAPIsBlocked)
417 IPC_MESSAGE_HANDLER(ViewHostMsg_DidLose3DContext, OnDidLose3DContext)
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100418#if defined(OS_ANDROID)
419 IPC_MESSAGE_HANDLER(ViewHostMsg_RunWebAudioMediaCodec, OnWebAudioMediaCodec)
420#endif
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000421 IPC_MESSAGE_UNHANDLED(handled = false)
422 IPC_END_MESSAGE_MAP_EX()
423
424 return handled;
425}
426
427void RenderMessageFilter::OnDestruct() const {
428 BrowserThread::DeleteOnIOThread::Destruct(this);
429}
430
431base::TaskRunner* RenderMessageFilter::OverrideTaskRunnerForMessage(
432 const IPC::Message& message) {
433#if defined(OS_WIN)
434 // Windows monitor profile must be read from a file.
435 if (message.type() == ViewHostMsg_GetMonitorColorProfile::ID)
436 return BrowserThread::GetBlockingPool();
437#endif
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +0100438#if defined(OS_MACOSX)
439 // OSX CoreAudio calls must all happen on the main thread.
440 if (message.type() == ViewHostMsg_GetAudioHardwareConfig::ID)
Ben Murdocheb525c52013-07-10 11:40:50 +0100441 return audio_manager_->GetMessageLoop().get();
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +0100442#endif
Ben Murdoch2385ea32013-08-06 11:01:04 +0100443 if (message.type() == ViewHostMsg_AsyncOpenPepperFile::ID)
444 return BrowserThread::GetBlockingPool();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000445 return NULL;
446}
447
448bool RenderMessageFilter::OffTheRecord() const {
449 return incognito_;
450}
451
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000452void RenderMessageFilter::OnCreateWindow(
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000453 const ViewHostMsg_CreateWindow_Params& params,
454 int* route_id,
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100455 int* main_frame_route_id,
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000456 int* surface_id,
457 int64* cloned_session_storage_namespace_id) {
458 bool no_javascript_access;
459 bool can_create_window =
460 GetContentClient()->browser()->CanCreateWindow(
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000461 params.opener_url,
462 params.opener_security_origin,
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000463 params.window_container_type,
Ben Murdoch558790d2013-07-30 15:19:42 +0100464 params.target_url,
465 params.referrer,
466 params.disposition,
467 params.features,
468 params.user_gesture,
469 params.opener_suppressed,
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000470 resource_context_,
471 render_process_id_,
Ben Murdoch558790d2013-07-30 15:19:42 +0100472 is_guest_,
473 params.opener_id,
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000474 &no_javascript_access);
475
476 if (!can_create_window) {
477 *route_id = MSG_ROUTING_NONE;
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100478 *main_frame_route_id = MSG_ROUTING_NONE;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000479 *surface_id = 0;
480 return;
481 }
482
483 // This will clone the sessionStorage for namespace_id_to_clone.
484 scoped_refptr<SessionStorageNamespaceImpl> cloned_namespace =
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100485 new SessionStorageNamespaceImpl(dom_storage_context_.get(),
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000486 params.session_storage_namespace_id);
487 *cloned_session_storage_namespace_id = cloned_namespace->id();
488
489 render_widget_helper_->CreateNewWindow(params,
490 no_javascript_access,
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100491 PeerHandle(),
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000492 route_id,
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100493 main_frame_route_id,
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000494 surface_id,
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100495 cloned_namespace.get());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000496}
497
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000498void RenderMessageFilter::OnCreateWidget(int opener_id,
499 WebKit::WebPopupType popup_type,
500 int* route_id,
501 int* surface_id) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000502 render_widget_helper_->CreateNewWidget(
503 opener_id, popup_type, route_id, surface_id);
504}
505
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000506void RenderMessageFilter::OnCreateFullscreenWidget(int opener_id,
507 int* route_id,
508 int* surface_id) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000509 render_widget_helper_->CreateNewFullscreenWidget(
510 opener_id, route_id, surface_id);
511}
512
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000513void RenderMessageFilter::OnGetProcessMemorySizes(size_t* private_bytes,
514 size_t* shared_bytes) {
515 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
516 using base::ProcessMetrics;
517#if !defined(OS_MACOSX) || defined(OS_IOS)
518 scoped_ptr<ProcessMetrics> metrics(ProcessMetrics::CreateProcessMetrics(
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100519 PeerHandle()));
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000520#else
521 scoped_ptr<ProcessMetrics> metrics(ProcessMetrics::CreateProcessMetrics(
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100522 PeerHandle(), content::BrowserChildProcessHost::GetPortProvider()));
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000523#endif
524 if (!metrics->GetMemoryBytes(private_bytes, shared_bytes)) {
525 *private_bytes = 0;
526 *shared_bytes = 0;
527 }
528}
529
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000530void RenderMessageFilter::OnSetCookie(const IPC::Message& message,
531 const GURL& url,
532 const GURL& first_party_for_cookies,
533 const std::string& cookie) {
534 ChildProcessSecurityPolicyImpl* policy =
535 ChildProcessSecurityPolicyImpl::GetInstance();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000536 if (!policy->CanAccessCookiesForOrigin(render_process_id_, url))
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000537 return;
538
539 net::CookieOptions options;
540 if (GetContentClient()->browser()->AllowSetCookie(
541 url, first_party_for_cookies, cookie,
542 resource_context_, render_process_id_, message.routing_id(),
543 &options)) {
544 net::URLRequestContext* context = GetRequestContextForURL(url);
545 // Pass a null callback since we don't care about when the 'set' completes.
546 context->cookie_store()->SetCookieWithOptionsAsync(
547 url, cookie, options, net::CookieMonster::SetCookiesCallback());
548 }
549}
550
551void RenderMessageFilter::OnGetCookies(const GURL& url,
552 const GURL& first_party_for_cookies,
553 IPC::Message* reply_msg) {
554 ChildProcessSecurityPolicyImpl* policy =
555 ChildProcessSecurityPolicyImpl::GetInstance();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000556 if (!policy->CanAccessCookiesForOrigin(render_process_id_, url)) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000557 SendGetCookiesResponse(reply_msg, std::string());
558 return;
559 }
560
561 // If we crash here, figure out what URL the renderer was requesting.
562 // http://crbug.com/99242
563 char url_buf[128];
564 base::strlcpy(url_buf, url.spec().c_str(), arraysize(url_buf));
565 base::debug::Alias(url_buf);
566
567 net::URLRequestContext* context = GetRequestContextForURL(url);
568 net::CookieMonster* cookie_monster =
569 context->cookie_store()->GetCookieMonster();
570 cookie_monster->GetAllCookiesForURLAsync(
571 url, base::Bind(&RenderMessageFilter::CheckPolicyForCookies, this, url,
572 first_party_for_cookies, reply_msg));
573}
574
575void RenderMessageFilter::OnGetRawCookies(
576 const GURL& url,
577 const GURL& first_party_for_cookies,
578 IPC::Message* reply_msg) {
579 ChildProcessSecurityPolicyImpl* policy =
580 ChildProcessSecurityPolicyImpl::GetInstance();
581 // Only return raw cookies to trusted renderers or if this request is
582 // not targeted to an an external host like ChromeFrame.
583 // TODO(ananta) We need to support retreiving raw cookies from external
584 // hosts.
585 if (!policy->CanReadRawCookies(render_process_id_) ||
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000586 !policy->CanAccessCookiesForOrigin(render_process_id_, url)) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000587 SendGetRawCookiesResponse(reply_msg, net::CookieList());
588 return;
589 }
590
591 // We check policy here to avoid sending back cookies that would not normally
592 // be applied to outbound requests for the given URL. Since this cookie info
593 // is visible in the developer tools, it is helpful to make it match reality.
594 net::URLRequestContext* context = GetRequestContextForURL(url);
595 net::CookieMonster* cookie_monster =
596 context->cookie_store()->GetCookieMonster();
597 cookie_monster->GetAllCookiesForURLAsync(
598 url, base::Bind(&RenderMessageFilter::SendGetRawCookiesResponse,
599 this, reply_msg));
600}
601
602void RenderMessageFilter::OnDeleteCookie(const GURL& url,
603 const std::string& cookie_name) {
604 ChildProcessSecurityPolicyImpl* policy =
605 ChildProcessSecurityPolicyImpl::GetInstance();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000606 if (!policy->CanAccessCookiesForOrigin(render_process_id_, url))
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000607 return;
608
609 net::URLRequestContext* context = GetRequestContextForURL(url);
610 context->cookie_store()->DeleteCookieAsync(url, cookie_name, base::Closure());
611}
612
613void RenderMessageFilter::OnCookiesEnabled(
614 const GURL& url,
615 const GURL& first_party_for_cookies,
616 bool* cookies_enabled) {
617 // TODO(ananta): If this render view is associated with an automation channel,
618 // aka ChromeFrame then we need to retrieve cookie settings from the external
619 // host.
620 *cookies_enabled = GetContentClient()->browser()->AllowGetCookie(
621 url, first_party_for_cookies, net::CookieList(), resource_context_,
622 render_process_id_, MSG_ROUTING_CONTROL);
623}
624
625#if defined(OS_MACOSX)
626void RenderMessageFilter::OnLoadFont(const FontDescriptor& font,
627 IPC::Message* reply_msg) {
628 FontLoader::Result* result = new FontLoader::Result;
629
630 BrowserThread::PostTaskAndReply(
631 BrowserThread::FILE, FROM_HERE,
632 base::Bind(&FontLoader::LoadFont, font, result),
633 base::Bind(&RenderMessageFilter::SendLoadFontReply, this, reply_msg,
634 base::Owned(result)));
635}
636
637void RenderMessageFilter::SendLoadFontReply(IPC::Message* reply,
638 FontLoader::Result* result) {
639 base::SharedMemoryHandle handle;
640 if (result->font_data_size == 0 || result->font_id == 0) {
641 result->font_data_size = 0;
642 result->font_id = 0;
643 handle = base::SharedMemory::NULLHandle();
644 } else {
645 result->font_data.GiveToProcess(base::GetCurrentProcessHandle(), &handle);
646 }
647 ViewHostMsg_LoadFont::WriteReplyParams(
648 reply, result->font_data_size, handle, result->font_id);
649 Send(reply);
650}
651#endif // OS_MACOSX
652
653void RenderMessageFilter::OnGetPlugins(
654 bool refresh,
655 IPC::Message* reply_msg) {
656 // Don't refresh if the specified threshold has not been passed. Note that
657 // this check is performed before off-loading to the file thread. The reason
658 // we do this is that some pages tend to request that the list of plugins be
659 // refreshed at an excessive rate. This instigates disk scanning, as the list
660 // is accumulated by doing multiple reads from disk. This effect is
661 // multiplied when we have several pages requesting this operation.
662 if (refresh) {
663 const base::TimeDelta threshold = base::TimeDelta::FromSeconds(
664 kPluginsRefreshThresholdInSeconds);
665 const base::TimeTicks now = base::TimeTicks::Now();
666 if (now - last_plugin_refresh_time_ >= threshold) {
667 // Only refresh if the threshold hasn't been exceeded yet.
668 PluginServiceImpl::GetInstance()->RefreshPlugins();
669 last_plugin_refresh_time_ = now;
670 }
671 }
672
673 PluginServiceImpl::GetInstance()->GetPlugins(
674 base::Bind(&RenderMessageFilter::GetPluginsCallback, this, reply_msg));
675}
676
677void RenderMessageFilter::GetPluginsCallback(
678 IPC::Message* reply_msg,
Ben Murdochca12bfa2013-07-23 11:17:05 +0100679 const std::vector<WebPluginInfo>& all_plugins) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000680 // Filter the plugin list.
681 PluginServiceFilter* filter = PluginServiceImpl::GetInstance()->GetFilter();
Ben Murdochca12bfa2013-07-23 11:17:05 +0100682 std::vector<WebPluginInfo> plugins;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000683
684 int child_process_id = -1;
685 int routing_id = MSG_ROUTING_NONE;
686 for (size_t i = 0; i < all_plugins.size(); ++i) {
687 // Copy because the filter can mutate.
Ben Murdochca12bfa2013-07-23 11:17:05 +0100688 WebPluginInfo plugin(all_plugins[i]);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000689 if (!filter || filter->IsPluginAvailable(child_process_id,
690 routing_id,
691 resource_context_,
692 GURL(),
693 GURL(),
694 &plugin)) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000695 plugins.push_back(plugin);
696 }
697 }
698
699 ViewHostMsg_GetPlugins::WriteReplyParams(reply_msg, plugins);
700 Send(reply_msg);
701}
702
703void RenderMessageFilter::OnGetPluginInfo(
704 int routing_id,
705 const GURL& url,
706 const GURL& page_url,
707 const std::string& mime_type,
708 bool* found,
Ben Murdochca12bfa2013-07-23 11:17:05 +0100709 WebPluginInfo* info,
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000710 std::string* actual_mime_type) {
711 bool allow_wildcard = true;
712 *found = plugin_service_->GetPluginInfo(
713 render_process_id_, routing_id, resource_context_,
714 url, page_url, mime_type, allow_wildcard,
715 NULL, info, actual_mime_type);
716}
717
718void RenderMessageFilter::OnOpenChannelToPlugin(int routing_id,
719 const GURL& url,
720 const GURL& policy_url,
721 const std::string& mime_type,
722 IPC::Message* reply_msg) {
723 OpenChannelToNpapiPluginCallback* client =
724 new OpenChannelToNpapiPluginCallback(this, resource_context_, reply_msg);
725 DCHECK(!ContainsKey(plugin_host_clients_, client));
726 plugin_host_clients_.insert(client);
727 plugin_service_->OpenChannelToNpapiPlugin(
728 render_process_id_, routing_id,
729 url, policy_url, mime_type, client);
730}
731
732void RenderMessageFilter::OnOpenChannelToPepperPlugin(
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000733 const base::FilePath& path,
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000734 IPC::Message* reply_msg) {
735 plugin_service_->OpenChannelToPpapiPlugin(
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000736 render_process_id_,
737 path,
738 profile_data_directory_,
739 new OpenChannelToPpapiPluginCallback(this, resource_context_, reply_msg));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000740}
741
742void RenderMessageFilter::OnDidCreateOutOfProcessPepperInstance(
743 int plugin_child_id,
744 int32 pp_instance,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000745 PepperRendererInstanceData instance_data,
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000746 bool is_external) {
747 // It's important that we supply the render process ID ourselves based on the
748 // channel the message arrived on. We use the
749 // PP_Instance -> (process id, view id)
750 // mapping to decide how to handle messages received from the (untrusted)
751 // plugin, so an exploited renderer must not be able to insert fake mappings
752 // that may allow it access to other render processes.
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +0100753 DCHECK_EQ(0, instance_data.render_process_id);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000754 instance_data.render_process_id = render_process_id_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000755 if (is_external) {
756 // We provide the BrowserPpapiHost to the embedder, so it's safe to cast.
757 BrowserPpapiHostImpl* host = static_cast<BrowserPpapiHostImpl*>(
758 GetContentClient()->browser()->GetExternalBrowserPpapiHost(
759 plugin_child_id));
760 if (host)
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000761 host->AddInstance(pp_instance, instance_data);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000762 } else {
763 PpapiPluginProcessHost::DidCreateOutOfProcessInstance(
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000764 plugin_child_id, pp_instance, instance_data);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000765 }
766}
767
768void RenderMessageFilter::OnDidDeleteOutOfProcessPepperInstance(
769 int plugin_child_id,
770 int32 pp_instance,
771 bool is_external) {
772 if (is_external) {
773 // We provide the BrowserPpapiHost to the embedder, so it's safe to cast.
774 BrowserPpapiHostImpl* host = static_cast<BrowserPpapiHostImpl*>(
775 GetContentClient()->browser()->GetExternalBrowserPpapiHost(
776 plugin_child_id));
777 if (host)
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000778 host->DeleteInstance(pp_instance);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000779 } else {
780 PpapiPluginProcessHost::DidDeleteOutOfProcessInstance(
781 plugin_child_id, pp_instance);
782 }
783}
784
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000785void RenderMessageFilter::OnOpenChannelToPpapiBroker(
786 int routing_id,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000787 const base::FilePath& path) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000788 plugin_service_->OpenChannelToPpapiBroker(
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000789 render_process_id_,
790 path,
Ben Murdoch32409262013-08-07 11:04:47 +0100791 new OpenChannelToPpapiBrokerCallback(this, routing_id));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000792}
793
794void RenderMessageFilter::OnGenerateRoutingID(int* route_id) {
795 *route_id = render_widget_helper_->GetNextRoutingID();
796}
797
798void RenderMessageFilter::OnGetCPUUsage(int* cpu_usage) {
799 base::TimeTicks now = base::TimeTicks::Now();
800 int64 since_last_sample_ms = (now - cpu_usage_sample_time_).InMilliseconds();
801 if (since_last_sample_ms > kCPUUsageSampleIntervalMs) {
802 cpu_usage_sample_time_ = now;
803 cpu_usage_ = static_cast<int>(process_metrics_->GetCPUUsage());
804 }
805 *cpu_usage = cpu_usage_;
806}
807
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000808void RenderMessageFilter::OnGetAudioHardwareConfig(
809 media::AudioParameters* input_params,
810 media::AudioParameters* output_params) {
811 DCHECK(input_params);
812 DCHECK(output_params);
Ben Murdocheb525c52013-07-10 11:40:50 +0100813 *output_params = audio_manager_->GetDefaultOutputStreamParameters();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000814
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000815 // TODO(henrika): add support for all available input devices.
Ben Murdocheb525c52013-07-10 11:40:50 +0100816 *input_params = audio_manager_->GetInputStreamParameters(
817 media::AudioManagerBase::kDefaultDeviceId);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000818}
819
820void RenderMessageFilter::OnGetMonitorColorProfile(std::vector<char>* profile) {
821#if defined(OS_WIN)
822 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO));
823 if (BackingStoreWin::ColorManagementEnabled())
824 return;
825#endif
826 *profile = g_color_profile.Get().profile();
827}
828
829void RenderMessageFilter::OnDownloadUrl(const IPC::Message& message,
830 const GURL& url,
831 const Referrer& referrer,
832 const string16& suggested_name) {
833 scoped_ptr<DownloadSaveInfo> save_info(new DownloadSaveInfo());
834 save_info->suggested_name = suggested_name;
835 scoped_ptr<net::URLRequest> request(
836 resource_context_->GetRequestContext()->CreateRequest(url, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000837 RecordDownloadSource(INITIATED_BY_RENDERER);
838 resource_dispatcher_host_->BeginDownload(
839 request.Pass(),
Ben Murdocheb525c52013-07-10 11:40:50 +0100840 referrer,
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000841 true, // is_content_initiated
842 resource_context_,
843 render_process_id_,
844 message.routing_id(),
845 false,
846 save_info.Pass(),
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100847 content::DownloadItem::kInvalidId,
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000848 ResourceDispatcherHostImpl::DownloadStartedCallback());
849}
850
851void RenderMessageFilter::OnCheckNotificationPermission(
852 const GURL& source_origin, int* result) {
853#if defined(ENABLE_NOTIFICATIONS)
854 *result = GetContentClient()->browser()->
855 CheckDesktopNotificationPermission(source_origin, resource_context_,
856 render_process_id_);
857#else
858 *result = WebKit::WebNotificationPresenter::PermissionAllowed;
859#endif
860}
861
862void RenderMessageFilter::OnAllocateSharedMemory(
863 uint32 buffer_size,
864 base::SharedMemoryHandle* handle) {
865 ChildProcessHostImpl::AllocateSharedMemory(
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100866 buffer_size, PeerHandle(), handle);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000867}
868
869net::URLRequestContext* RenderMessageFilter::GetRequestContextForURL(
870 const GURL& url) {
871 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
872
873 net::URLRequestContext* context =
874 GetContentClient()->browser()->OverrideRequestContextForURL(
875 url, resource_context_);
876 if (!context)
877 context = request_context_->GetURLRequestContext();
878
879 return context;
880}
881
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100882#if defined(OS_POSIX) && !defined(TOOLKIT_GTK) && !defined(OS_ANDROID)
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000883void RenderMessageFilter::OnAllocTransportDIB(
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100884 uint32 size, bool cache_in_browser, TransportDIB::Handle* handle) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000885 render_widget_helper_->AllocTransportDIB(size, cache_in_browser, handle);
886}
887
888void RenderMessageFilter::OnFreeTransportDIB(
889 TransportDIB::Id dib_id) {
890 render_widget_helper_->FreeTransportDIB(dib_id);
891}
892#endif
893
894bool RenderMessageFilter::CheckPreparsedJsCachingEnabled() const {
895 static bool checked = false;
896 static bool result = false;
897 if (!checked) {
898 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
899 result = command_line.HasSwitch(switches::kEnablePreparsedJsCaching);
900 checked = true;
901 }
902 return result;
903}
904
905void RenderMessageFilter::OnCacheableMetadataAvailable(
906 const GURL& url,
907 double expected_response_time,
908 const std::vector<char>& data) {
909 if (!CheckPreparsedJsCachingEnabled())
910 return;
911
912 net::HttpCache* cache = request_context_->GetURLRequestContext()->
913 http_transaction_factory()->GetCache();
914 DCHECK(cache);
915
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000916 // Use the same priority for the metadata write as for script
917 // resources (see defaultPriorityForResourceType() in WebKit's
918 // CachedResource.cpp). Note that WebURLRequest::PriorityMedium
919 // corresponds to net::LOW (see ConvertWebKitPriorityToNetPriority()
920 // in weburlloader_impl.cc).
921 const net::RequestPriority kPriority = net::LOW;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000922 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(data.size()));
923 memcpy(buf->data(), &data.front(), data.size());
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100924 cache->WriteMetadata(url,
925 kPriority,
926 base::Time::FromDoubleT(expected_response_time),
927 buf.get(),
928 data.size());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000929}
930
931void RenderMessageFilter::OnKeygen(uint32 key_size_index,
932 const std::string& challenge_string,
933 const GURL& url,
934 IPC::Message* reply_msg) {
935 // Map displayed strings indicating level of keysecurity in the <keygen>
936 // menu to the key size in bits. (See SSLKeyGeneratorChromium.cpp in WebCore.)
937 int key_size_in_bits;
938 switch (key_size_index) {
939 case 0:
940 key_size_in_bits = 2048;
941 break;
942 case 1:
943 key_size_in_bits = 1024;
944 break;
945 default:
946 DCHECK(false) << "Illegal key_size_index " << key_size_index;
947 ViewHostMsg_Keygen::WriteReplyParams(reply_msg, std::string());
948 Send(reply_msg);
949 return;
950 }
951
952 VLOG(1) << "Dispatching keygen task to worker pool.";
953 // Dispatch to worker pool, so we do not block the IO thread.
954 if (!base::WorkerPool::PostTask(
955 FROM_HERE,
956 base::Bind(
957 &RenderMessageFilter::OnKeygenOnWorkerThread, this,
958 key_size_in_bits, challenge_string, url, reply_msg),
959 true)) {
960 NOTREACHED() << "Failed to dispatch keygen task to worker pool";
961 ViewHostMsg_Keygen::WriteReplyParams(reply_msg, std::string());
962 Send(reply_msg);
963 return;
964 }
965}
966
967void RenderMessageFilter::OnKeygenOnWorkerThread(
968 int key_size_in_bits,
969 const std::string& challenge_string,
970 const GURL& url,
971 IPC::Message* reply_msg) {
972 DCHECK(reply_msg);
973
974 // Generate a signed public key and challenge, then send it back.
975 net::KeygenHandler keygen_handler(key_size_in_bits, challenge_string, url);
976
977#if defined(USE_NSS)
978 // Attach a password delegate so we can authenticate.
979 keygen_handler.set_crypto_module_password_delegate(
980 GetContentClient()->browser()->GetCryptoPasswordDelegate(url));
981#endif // defined(USE_NSS)
982
983 ViewHostMsg_Keygen::WriteReplyParams(
984 reply_msg,
985 keygen_handler.GenKeyAndSignChallenge());
986 Send(reply_msg);
987}
988
Ben Murdoch2385ea32013-08-06 11:01:04 +0100989void RenderMessageFilter::OnAsyncOpenPepperFile(int routing_id,
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100990 const base::FilePath& path,
991 int pp_open_flags,
992 int message_id) {
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100993 int platform_file_flags = 0;
994 if (!CanOpenWithPepperFlags(pp_open_flags, render_process_id_, path) ||
995 !ppapi::PepperFileOpenFlagsToPlatformFileFlags(
996 pp_open_flags, &platform_file_flags)) {
997 DLOG(ERROR) <<
998 "Bad pp_open_flags in ViewMsgHost_AsyncOpenPepperFile message: " <<
999 pp_open_flags;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001000 RecordAction(UserMetricsAction("BadMessageTerminate_AOF"));
1001 BadMessageReceived();
1002 return;
1003 }
1004
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001005 base::PlatformFileError error_code = base::PLATFORM_FILE_OK;
1006 base::PlatformFile file = base::CreatePlatformFile(
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01001007 path, platform_file_flags, NULL, &error_code);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001008 IPC::PlatformFileForTransit file_for_transit =
1009 file != base::kInvalidPlatformFileValue ?
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01001010 IPC::GetFileHandleForProcess(file, PeerHandle(), true) :
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001011 IPC::InvalidPlatformFileForTransit();
1012
Ben Murdoch2385ea32013-08-06 11:01:04 +01001013 Send(new ViewMsg_AsyncOpenPepperFile_ACK(
1014 routing_id, error_code, file_for_transit, message_id));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001015}
1016
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001017void RenderMessageFilter::OnMediaLogEvents(
1018 const std::vector<media::MediaLogEvent>& events) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001019 if (media_internals_)
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001020 media_internals_->OnMediaEvents(render_process_id_, events);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001021}
1022
1023void RenderMessageFilter::CheckPolicyForCookies(
1024 const GURL& url,
1025 const GURL& first_party_for_cookies,
1026 IPC::Message* reply_msg,
1027 const net::CookieList& cookie_list) {
1028 net::URLRequestContext* context = GetRequestContextForURL(url);
1029 // Check the policy for get cookies, and pass cookie_list to the
1030 // TabSpecificContentSetting for logging purpose.
1031 if (GetContentClient()->browser()->AllowGetCookie(
1032 url, first_party_for_cookies, cookie_list, resource_context_,
1033 render_process_id_, reply_msg->routing_id())) {
1034 // Gets the cookies from cookie store if allowed.
1035 context->cookie_store()->GetCookiesWithOptionsAsync(
1036 url, net::CookieOptions(),
1037 base::Bind(&RenderMessageFilter::SendGetCookiesResponse,
1038 this, reply_msg));
1039 } else {
1040 SendGetCookiesResponse(reply_msg, std::string());
1041 }
1042}
1043
1044void RenderMessageFilter::SendGetCookiesResponse(IPC::Message* reply_msg,
1045 const std::string& cookies) {
1046 ViewHostMsg_GetCookies::WriteReplyParams(reply_msg, cookies);
1047 Send(reply_msg);
1048}
1049
1050void RenderMessageFilter::SendGetRawCookiesResponse(
1051 IPC::Message* reply_msg,
1052 const net::CookieList& cookie_list) {
Ben Murdocheb525c52013-07-10 11:40:50 +01001053 std::vector<CookieData> cookies;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001054 for (size_t i = 0; i < cookie_list.size(); ++i)
Ben Murdocheb525c52013-07-10 11:40:50 +01001055 cookies.push_back(CookieData(cookie_list[i]));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001056 ViewHostMsg_GetRawCookies::WriteReplyParams(reply_msg, cookies);
1057 Send(reply_msg);
1058}
1059
1060void RenderMessageFilter::OnCompletedOpenChannelToNpapiPlugin(
1061 OpenChannelToNpapiPluginCallback* client) {
1062 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1063 DCHECK(ContainsKey(plugin_host_clients_, client));
1064 plugin_host_clients_.erase(client);
1065}
1066
1067void RenderMessageFilter::OnUpdateIsDelayed(const IPC::Message& msg) {
1068 // When not in accelerated compositing mode, in certain cases (e.g. waiting
1069 // for a resize or if no backing store) the RenderWidgetHost is blocking the
1070 // UI thread for some time, waiting for an UpdateRect from the renderer. If we
1071 // are going to switch to accelerated compositing, the GPU process may need
1072 // round-trips to the UI thread before finishing the frame, causing deadlocks
1073 // if we delay the UpdateRect until we receive the OnSwapBuffersComplete. So
1074 // the renderer sent us this message, so that we can unblock the UI thread.
1075 // We will simply re-use the UpdateRect unblock mechanism, just with a
1076 // different message.
1077 render_widget_helper_->DidReceiveBackingStoreMsg(msg);
1078}
1079
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001080void RenderMessageFilter::OnAre3DAPIsBlocked(int render_view_id,
1081 const GURL& top_origin_url,
1082 ThreeDAPIType requester,
1083 bool* blocked) {
1084 *blocked = GpuDataManagerImpl::GetInstance()->Are3DAPIsBlocked(
1085 top_origin_url, render_process_id_, render_view_id, requester);
1086}
1087
1088void RenderMessageFilter::OnDidLose3DContext(
1089 const GURL& top_origin_url,
1090 ThreeDAPIType /* unused */,
1091 int arb_robustness_status_code) {
1092#if defined(OS_MACOSX)
1093 // TODO(kbr): this file indirectly includes npapi.h, which on Mac
1094 // OS pulls in the system OpenGL headers. For some
1095 // not-yet-investigated reason this breaks the build with the 10.6
1096 // SDK but not 10.7. For now work around this in a way compatible
1097 // with the Khronos headers.
1098#ifndef GL_GUILTY_CONTEXT_RESET_ARB
1099#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253
1100#endif
1101#ifndef GL_INNOCENT_CONTEXT_RESET_ARB
1102#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254
1103#endif
1104#ifndef GL_UNKNOWN_CONTEXT_RESET_ARB
1105#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255
1106#endif
1107
1108#endif
1109 GpuDataManagerImpl::DomainGuilt guilt;
1110 switch (arb_robustness_status_code) {
1111 case GL_GUILTY_CONTEXT_RESET_ARB:
1112 guilt = GpuDataManagerImpl::DOMAIN_GUILT_KNOWN;
1113 break;
1114 case GL_UNKNOWN_CONTEXT_RESET_ARB:
1115 guilt = GpuDataManagerImpl::DOMAIN_GUILT_UNKNOWN;
1116 break;
1117 default:
1118 // Ignore lost contexts known to be innocent.
1119 return;
1120 }
1121
1122 GpuDataManagerImpl::GetInstance()->BlockDomainFrom3DAPIs(
1123 top_origin_url, guilt);
1124}
1125
1126#if defined(OS_WIN)
1127void RenderMessageFilter::OnPreCacheFontCharacters(const LOGFONT& font,
1128 const string16& str) {
1129 // First, comments from FontCacheDispatcher::OnPreCacheFont do apply here too.
1130 // Except that for True Type fonts,
1131 // GetTextMetrics will not load the font in memory.
1132 // The only way windows seem to load properly, it is to create a similar
1133 // device (like the one in which we print), then do an ExtTextOut,
1134 // as we do in the printing thread, which is sandboxed.
1135 HDC hdc = CreateEnhMetaFile(NULL, NULL, NULL, NULL);
1136 HFONT font_handle = CreateFontIndirect(&font);
1137 DCHECK(NULL != font_handle);
1138
1139 HGDIOBJ old_font = SelectObject(hdc, font_handle);
1140 DCHECK(NULL != old_font);
1141
1142 ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, str.c_str(), str.length(), NULL);
1143
1144 SelectObject(hdc, old_font);
1145 DeleteObject(font_handle);
1146
1147 HENHMETAFILE metafile = CloseEnhMetaFile(hdc);
1148
1149 if (metafile) {
1150 DeleteEnhMetaFile(metafile);
1151 }
1152}
1153#endif
1154
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001155#if defined(OS_ANDROID)
1156void RenderMessageFilter::OnWebAudioMediaCodec(
1157 base::SharedMemoryHandle encoded_data_handle,
1158 base::FileDescriptor pcm_output,
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +01001159 uint32_t data_size) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001160 // Let a WorkerPool handle this request since the WebAudio
1161 // MediaCodec bridge is slow and can block while sending the data to
1162 // the renderer.
1163 base::WorkerPool::PostTask(
1164 FROM_HERE,
1165 base::Bind(&media::WebAudioMediaCodecBridge::RunWebAudioMediaCodec,
1166 encoded_data_handle, pcm_output, data_size),
1167 true);
1168}
1169#endif
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001170} // namespace content