Home | History | Annotate | Download | only in renderer_host
      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:
    124   RenderMessageCompletionCallback(RenderMessageFilter* filter,
    125                                   IPC::Message* reply_msg)
    126       : filter_(filter),
    127         reply_msg_(reply_msg) {
    128   }
    129 
    130   virtual ~RenderMessageCompletionCallback() {
    131   }
    132 
    133   RenderMessageFilter* filter() { return filter_.get(); }
    134   IPC::Message* reply_msg() { return reply_msg_; }
    135 
    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:
    150   OpenChannelToPpapiPluginCallback(RenderMessageFilter* filter,
    151                                    ResourceContext* context,
    152                                    IPC::Message* reply_msg)
    153       : RenderMessageCompletionCallback(filter, reply_msg),
    154         context_(context) {
    155   }
    156 
    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 
    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 
    171   virtual bool OffTheRecord() OVERRIDE {
    172     return filter()->OffTheRecord();
    173   }
    174 
    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:
    186   OpenChannelToPpapiBrokerCallback(RenderMessageFilter* filter,
    187                                    int routing_id)
    188       : filter_(filter),
    189         routing_id_(routing_id) {
    190   }
    191 
    192   virtual ~OpenChannelToPpapiBrokerCallback() {}
    193 
    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 
    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 
    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:
    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 
    233   virtual int ID() OVERRIDE {
    234     return filter()->render_process_id();
    235   }
    236 
    237   virtual ResourceContext* GetResourceContext() OVERRIDE {
    238     return context_;
    239   }
    240 
    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 
    255   virtual void SetPluginInfo(const WebPluginInfo& info) OVERRIDE {
    256     info_ = info;
    257   }
    258 
    259   virtual void OnFoundPluginProcessHost(PluginProcessHost* host) OVERRIDE {
    260     DCHECK(host);
    261     host_ = host;
    262   }
    263 
    264   virtual void OnSentPluginChannelRequest() OVERRIDE {
    265     sent_plugin_channel_request_ = true;
    266   }
    267 
    268   virtual void OnChannelOpened(const IPC::ChannelHandle& handle) OVERRIDE {
    269     WriteReplyAndDeleteThis(handle);
    270   }
    271 
    272   virtual void OnError() OVERRIDE {
    273     WriteReplyAndDeleteThis(IPC::ChannelHandle());
    274   }
    275 
    276   PluginProcessHost* host() const {
    277     return host_;
    278   }
    279 
    280   bool sent_plugin_channel_request() const {
    281     return sent_plugin_channel_request_;
    282   }
    283 
    284   void Cancel() {
    285     delete this;
    286   }
    287 
    288  private:
    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 
    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 
    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 
    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 
    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 
    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 
    446 void RenderMessageFilter::OnDestruct() const {
    447   BrowserThread::DeleteOnIOThread::Destruct(this);
    448 }
    449 
    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 
    463 bool RenderMessageFilter::OffTheRecord() const {
    464   return incognito_;
    465 }
    466 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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)
    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 
    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)
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    821 void RenderMessageFilter::OnGenerateRoutingID(int* route_id) {
    822   *route_id = render_widget_helper_->GetNextRoutingID();
    823 }
    824 
    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 
    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)
    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 
    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 
    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 
    898 void RenderMessageFilter::OnAllocateSharedMemory(
    899     uint32 buffer_size,
    900     base::SharedMemoryHandle* handle) {
    901   ChildProcessHostImpl::AllocateSharedMemory(
    902       buffer_size, PeerHandle(), handle);
    903 }
    904 
    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 
    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 
    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 
    938 void RenderMessageFilter::OnDeletedSharedBitmap(const cc::SharedBitmapId& id) {
    939   HostSharedBitmapManager::current()->ChildDeletedSharedBitmap(id);
    940 }
    941 
    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)
    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 
    974 void RenderMessageFilter::OnFreeTransportDIB(
    975     TransportDIB::Id dib_id) {
    976   render_widget_helper_->FreeTransportDIB(dib_id);
    977 }
    978 #endif
    979 
    980 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 
    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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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)
   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)
   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