Home | History | Annotate | Download | only in pepper
      1 // Copyright 2013 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/pepper_renderer_connection.h"
      6 
      7 #include "content/browser/browser_child_process_host_impl.h"
      8 #include "content/browser/ppapi_plugin_process_host.h"
      9 #include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h"
     10 #include "content/common/pepper_renderer_instance_data.h"
     11 #include "content/common/view_messages.h"
     12 #include "content/browser/renderer_host/pepper/pepper_file_ref_host.h"
     13 #include "content/public/browser/content_browser_client.h"
     14 #include "content/public/common/content_client.h"
     15 #include "ipc/ipc_message_macros.h"
     16 #include "ppapi/host/resource_host.h"
     17 #include "ppapi/proxy/ppapi_message_utils.h"
     18 #include "ppapi/proxy/ppapi_messages.h"
     19 #include "ppapi/proxy/resource_message_params.h"
     20 
     21 namespace content {
     22 
     23 PepperRendererConnection::PepperRendererConnection(int render_process_id)
     24     : render_process_id_(render_process_id) {
     25   // Only give the renderer permission for stable APIs.
     26   in_process_host_.reset(new BrowserPpapiHostImpl(this,
     27                                                   ppapi::PpapiPermissions(),
     28                                                   "",
     29                                                   base::FilePath(),
     30                                                   base::FilePath(),
     31                                                   false,
     32                                                   NULL));
     33 }
     34 
     35 PepperRendererConnection::~PepperRendererConnection() {
     36 }
     37 
     38 BrowserPpapiHostImpl* PepperRendererConnection::GetHostForChildProcess(
     39     int child_process_id) const {
     40   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
     41 
     42   // Find the plugin which this message refers to. Check NaCl plugins first.
     43   BrowserPpapiHostImpl* host = static_cast<BrowserPpapiHostImpl*>(
     44       GetContentClient()->browser()->GetExternalBrowserPpapiHost(
     45           child_process_id));
     46 
     47   if (!host) {
     48     // Check trusted pepper plugins.
     49     for (PpapiPluginProcessHostIterator iter; !iter.Done(); ++iter) {
     50       if (iter->process() &&
     51           iter->process()->GetData().id == child_process_id) {
     52         // Found the plugin.
     53         host = iter->host_impl();
     54         break;
     55       }
     56     }
     57   }
     58 
     59   // If the message is being sent from an in-process plugin, we own the
     60   // BrowserPpapiHost.
     61   if (!host && child_process_id == 0) {
     62     host = in_process_host_.get();
     63   }
     64 
     65   return host;
     66 }
     67 
     68 bool PepperRendererConnection::OnMessageReceived(const IPC::Message& msg,
     69                                                  bool* message_was_ok) {
     70   if (in_process_host_->GetPpapiHost()->OnMessageReceived(msg))
     71     return true;
     72 
     73   bool handled = true;
     74   IPC_BEGIN_MESSAGE_MAP_EX(PepperRendererConnection, msg, *message_was_ok)
     75     IPC_MESSAGE_HANDLER(PpapiHostMsg_CreateResourceHostFromHost,
     76                         OnMsgCreateResourceHostFromHost)
     77     IPC_MESSAGE_HANDLER(PpapiHostMsg_FileRef_GetInfoForRenderer,
     78                         OnMsgFileRefGetInfoForRenderer)
     79     IPC_MESSAGE_HANDLER(ViewHostMsg_DidCreateInProcessInstance,
     80                         OnMsgDidCreateInProcessInstance)
     81     IPC_MESSAGE_HANDLER(ViewHostMsg_DidDeleteInProcessInstance,
     82                         OnMsgDidDeleteInProcessInstance)
     83     IPC_MESSAGE_UNHANDLED(handled = false)
     84   IPC_END_MESSAGE_MAP_EX()
     85 
     86   return handled;
     87 }
     88 
     89 void PepperRendererConnection::OnMsgCreateResourceHostFromHost(
     90     int routing_id,
     91     int child_process_id,
     92     const ppapi::proxy::ResourceMessageCallParams& params,
     93     PP_Instance instance,
     94     const IPC::Message& nested_msg) {
     95   BrowserPpapiHostImpl* host = GetHostForChildProcess(child_process_id);
     96 
     97   int pending_resource_host_id;
     98   if (!host) {
     99     DLOG(ERROR) << "Invalid plugin process ID.";
    100     pending_resource_host_id = 0;
    101   } else {
    102     // FileRef_CreateExternal is only permitted from the renderer. Because of
    103     // this, we handle this message here and not in
    104     // content_browser_pepper_host_factory.cc.
    105     scoped_ptr<ppapi::host::ResourceHost> resource_host;
    106     if (host->IsValidInstance(instance)) {
    107       if (nested_msg.type() == PpapiHostMsg_FileRef_CreateExternal::ID) {
    108         base::FilePath external_path;
    109         if (ppapi::UnpackMessage<PpapiHostMsg_FileRef_CreateExternal>(
    110             nested_msg, &external_path)) {
    111           resource_host.reset(new PepperFileRefHost(
    112               host, instance, params.pp_resource(), external_path));
    113         }
    114       }
    115     }
    116 
    117     if (!resource_host.get()) {
    118       resource_host = host->GetPpapiHost()->CreateResourceHost(params,
    119                                                                instance,
    120                                                                nested_msg);
    121     }
    122     pending_resource_host_id =
    123         host->GetPpapiHost()->AddPendingResourceHost(resource_host.Pass());
    124   }
    125 
    126   Send(new PpapiHostMsg_CreateResourceHostFromHostReply(
    127        routing_id, params.sequence(), pending_resource_host_id));
    128 }
    129 
    130 void PepperRendererConnection::OnMsgFileRefGetInfoForRenderer(
    131     int routing_id,
    132     int child_process_id,
    133     int32_t sequence,
    134     const std::vector<PP_Resource>& resources) {
    135   std::vector<PP_Resource> out_resources;
    136   std::vector<PP_FileSystemType> fs_types;
    137   std::vector<std::string> file_system_url_specs;
    138   std::vector<base::FilePath> external_paths;
    139 
    140   BrowserPpapiHostImpl* host = GetHostForChildProcess(child_process_id);
    141   if (host) {
    142     for (size_t i = 0; i < resources.size(); ++i) {
    143       ppapi::host::ResourceHost* resource_host =
    144           host->GetPpapiHost()->GetResourceHost(resources[i]);
    145       if (resource_host && resource_host->IsFileRefHost()) {
    146         PepperFileRefHost* file_ref_host =
    147             static_cast<PepperFileRefHost*>(resource_host);
    148         out_resources.push_back(resources[i]);
    149         fs_types.push_back(file_ref_host->GetFileSystemType());
    150         file_system_url_specs.push_back(file_ref_host->GetFileSystemURLSpec());
    151         external_paths.push_back(file_ref_host->GetExternalPath());
    152       }
    153     }
    154   }
    155   Send(new PpapiHostMsg_FileRef_GetInfoForRendererReply(
    156        routing_id,
    157        sequence,
    158        out_resources,
    159        fs_types,
    160        file_system_url_specs,
    161        external_paths));
    162 }
    163 
    164 void PepperRendererConnection::OnMsgDidCreateInProcessInstance(
    165     PP_Instance instance,
    166     const PepperRendererInstanceData& instance_data) {
    167   PepperRendererInstanceData data = instance_data;
    168   data.render_process_id = render_process_id_;
    169   in_process_host_->AddInstance(instance, data);
    170 }
    171 
    172 void PepperRendererConnection::OnMsgDidDeleteInProcessInstance(
    173     PP_Instance instance) {
    174   in_process_host_->DeleteInstance(instance);
    175 }
    176 
    177 }  // namespace content
    178