Home | History | Annotate | Download | only in pepper
      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/pepper/browser_ppapi_host_impl.h"
      6 
      7 #include "content/browser/tracing/trace_message_filter.h"
      8 #include "content/common/pepper_renderer_instance_data.h"
      9 #include "content/public/browser/render_view_host.h"
     10 #include "content/public/common/process_type.h"
     11 #include "ipc/ipc_message_macros.h"
     12 
     13 namespace content {
     14 
     15 // static
     16 BrowserPpapiHost* BrowserPpapiHost::CreateExternalPluginProcess(
     17     IPC::Sender* sender,
     18     ppapi::PpapiPermissions permissions,
     19     base::ProcessHandle plugin_child_process,
     20     IPC::ChannelProxy* channel,
     21     net::HostResolver* host_resolver,
     22     int render_process_id,
     23     int render_view_id,
     24     const base::FilePath& profile_directory) {
     25   scoped_refptr<PepperMessageFilter> pepper_message_filter(
     26       new PepperMessageFilter(permissions,
     27                               host_resolver,
     28                               render_process_id,
     29                               render_view_id));
     30 
     31   // The plugin name and path shouldn't be needed for external plugins.
     32   BrowserPpapiHostImpl* browser_ppapi_host =
     33       new BrowserPpapiHostImpl(sender, permissions, std::string(),
     34                                base::FilePath(), profile_directory, true,
     35                                pepper_message_filter);
     36   browser_ppapi_host->set_plugin_process_handle(plugin_child_process);
     37 
     38   channel->AddFilter(pepper_message_filter);
     39   channel->AddFilter(browser_ppapi_host->message_filter().get());
     40   channel->AddFilter(new TraceMessageFilter());
     41 
     42   return browser_ppapi_host;
     43 }
     44 
     45 BrowserPpapiHostImpl::BrowserPpapiHostImpl(
     46     IPC::Sender* sender,
     47     const ppapi::PpapiPermissions& permissions,
     48     const std::string& plugin_name,
     49     const base::FilePath& plugin_path,
     50     const base::FilePath& profile_data_directory,
     51     bool external_plugin,
     52     const scoped_refptr<PepperMessageFilter>& pepper_message_filter)
     53     : ppapi_host_(new ppapi::host::PpapiHost(sender, permissions)),
     54       plugin_process_handle_(base::kNullProcessHandle),
     55       plugin_name_(plugin_name),
     56       plugin_path_(plugin_path),
     57       profile_data_directory_(profile_data_directory),
     58       external_plugin_(external_plugin) {
     59   message_filter_ = new HostMessageFilter(ppapi_host_.get());
     60   ppapi_host_->AddHostFactoryFilter(scoped_ptr<ppapi::host::HostFactory>(
     61       new ContentBrowserPepperHostFactory(this, pepper_message_filter)));
     62 }
     63 
     64 BrowserPpapiHostImpl::~BrowserPpapiHostImpl() {
     65   // Notify the filter so it won't foward messages to us.
     66   message_filter_->OnHostDestroyed();
     67 
     68   // Delete the host explicitly first. This shutdown will destroy the
     69   // resources, which may want to do cleanup in their destructors and expect
     70   // their pointers to us to be valid.
     71   ppapi_host_.reset();
     72 }
     73 
     74 ppapi::host::PpapiHost* BrowserPpapiHostImpl::GetPpapiHost() {
     75   return ppapi_host_.get();
     76 }
     77 
     78 base::ProcessHandle BrowserPpapiHostImpl::GetPluginProcessHandle() const {
     79   // Handle should previously have been set before use.
     80   DCHECK(plugin_process_handle_ != base::kNullProcessHandle);
     81   return plugin_process_handle_;
     82 }
     83 
     84 bool BrowserPpapiHostImpl::IsValidInstance(PP_Instance instance) const {
     85   return instance_map_.find(instance) != instance_map_.end();
     86 }
     87 
     88 bool BrowserPpapiHostImpl::GetRenderViewIDsForInstance(
     89     PP_Instance instance,
     90     int* render_process_id,
     91     int* render_view_id) const {
     92   InstanceMap::const_iterator found = instance_map_.find(instance);
     93   if (found == instance_map_.end()) {
     94     *render_process_id = 0;
     95     *render_view_id = 0;
     96     return false;
     97   }
     98 
     99   *render_process_id = found->second.render_process_id;
    100   *render_view_id = found->second.render_view_id;
    101   return true;
    102 }
    103 
    104 const std::string& BrowserPpapiHostImpl::GetPluginName() {
    105   return plugin_name_;
    106 }
    107 
    108 const base::FilePath& BrowserPpapiHostImpl::GetPluginPath() {
    109   return plugin_path_;
    110 }
    111 
    112 const base::FilePath& BrowserPpapiHostImpl::GetProfileDataDirectory() {
    113   return profile_data_directory_;
    114 }
    115 
    116 GURL BrowserPpapiHostImpl::GetDocumentURLForInstance(PP_Instance instance) {
    117   InstanceMap::const_iterator found = instance_map_.find(instance);
    118   if (found == instance_map_.end())
    119     return GURL();
    120   return found->second.document_url;
    121 }
    122 
    123 GURL BrowserPpapiHostImpl::GetPluginURLForInstance(PP_Instance instance) {
    124   InstanceMap::const_iterator found = instance_map_.find(instance);
    125   if (found == instance_map_.end())
    126     return GURL();
    127   return found->second.plugin_url;
    128 }
    129 
    130 void BrowserPpapiHostImpl::AddInstance(
    131     PP_Instance instance,
    132     const PepperRendererInstanceData& instance_data) {
    133   DCHECK(instance_map_.find(instance) == instance_map_.end());
    134   instance_map_[instance] = instance_data;
    135 }
    136 
    137 void BrowserPpapiHostImpl::DeleteInstance(PP_Instance instance) {
    138   InstanceMap::iterator found = instance_map_.find(instance);
    139   if (found == instance_map_.end()) {
    140     NOTREACHED();
    141     return;
    142   }
    143   instance_map_.erase(found);
    144 }
    145 
    146 bool BrowserPpapiHostImpl::HostMessageFilter::OnMessageReceived(
    147     const IPC::Message& msg) {
    148   // Don't forward messages if our owner object has been destroyed.
    149   if (!ppapi_host_)
    150     return false;
    151 
    152   /* TODO(brettw) when we add messages, here, the code should look like this:
    153   bool handled = true;
    154   IPC_BEGIN_MESSAGE_MAP(BrowserPpapiHostImpl, msg)
    155     // Add necessary message handlers here.
    156     IPC_MESSAGE_UNHANDLED(handled = ppapi_host_->OnMessageReceived(msg))
    157   IPC_END_MESSAGE_MAP();
    158   return handled;
    159   */
    160   return ppapi_host_->OnMessageReceived(msg);
    161 }
    162 
    163 void BrowserPpapiHostImpl::HostMessageFilter::OnHostDestroyed() {
    164   DCHECK(ppapi_host_);
    165   ppapi_host_ = NULL;
    166 }
    167 
    168 }  // namespace content
    169