Home | History | Annotate | Download | only in nacl_host
      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 "chrome/browser/nacl_host/nacl_host_message_filter.h"
      6 
      7 #include "chrome/browser/extensions/extension_info_map.h"
      8 #include "chrome/browser/nacl_host/nacl_browser.h"
      9 #include "chrome/browser/nacl_host/nacl_file_host.h"
     10 #include "chrome/browser/nacl_host/nacl_process_host.h"
     11 #include "chrome/browser/nacl_host/pnacl_host.h"
     12 #include "components/nacl/common/nacl_host_messages.h"
     13 #include "extensions/common/constants.h"
     14 #include "ipc/ipc_platform_file.h"
     15 #include "net/url_request/url_request_context.h"
     16 #include "net/url_request/url_request_context_getter.h"
     17 
     18 static base::FilePath GetManifestPath(
     19     ExtensionInfoMap* extension_info_map, const std::string& manifest) {
     20   GURL manifest_url(manifest);
     21   const extensions::Extension* extension = extension_info_map->extensions()
     22       .GetExtensionOrAppByURL(manifest_url);
     23   if (extension != NULL &&
     24       manifest_url.SchemeIs(extensions::kExtensionScheme)) {
     25     std::string path = manifest_url.path();
     26     TrimString(path, "/", &path);  // Remove first slash
     27     return extension->path().AppendASCII(path);
     28   }
     29   return base::FilePath();
     30 }
     31 
     32 NaClHostMessageFilter::NaClHostMessageFilter(
     33     int render_process_id,
     34     bool is_off_the_record,
     35     const base::FilePath& profile_directory,
     36     ExtensionInfoMap* extension_info_map,
     37     net::URLRequestContextGetter* request_context)
     38     : render_process_id_(render_process_id),
     39       off_the_record_(is_off_the_record),
     40       profile_directory_(profile_directory),
     41       request_context_(request_context),
     42       extension_info_map_(extension_info_map),
     43       weak_ptr_factory_(this) {
     44 }
     45 
     46 NaClHostMessageFilter::~NaClHostMessageFilter() {
     47 }
     48 
     49 void NaClHostMessageFilter::OnChannelClosing() {
     50   PnaclHost::GetInstance()->RendererClosing(render_process_id_);
     51   BrowserMessageFilter::OnChannelClosing();
     52 }
     53 
     54 bool NaClHostMessageFilter::OnMessageReceived(const IPC::Message& message,
     55                                               bool* message_was_ok) {
     56   bool handled = true;
     57   IPC_BEGIN_MESSAGE_MAP_EX(NaClHostMessageFilter, message, *message_was_ok)
     58 #if !defined(DISABLE_NACL)
     59     IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClHostMsg_LaunchNaCl, OnLaunchNaCl)
     60     IPC_MESSAGE_HANDLER(NaClHostMsg_EnsurePnaclInstalled,
     61                         OnEnsurePnaclInstalled)
     62     IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClHostMsg_GetReadonlyPnaclFD,
     63                                     OnGetReadonlyPnaclFd)
     64     IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClHostMsg_NaClCreateTemporaryFile,
     65                                     OnNaClCreateTemporaryFile)
     66     IPC_MESSAGE_HANDLER(NaClHostMsg_NexeTempFileRequest,
     67                         OnGetNexeFd)
     68     IPC_MESSAGE_HANDLER(NaClHostMsg_ReportTranslationFinished,
     69                         OnTranslationFinished)
     70     IPC_MESSAGE_HANDLER(NaClHostMsg_NaClErrorStatus, OnNaClErrorStatus)
     71     IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClHostMsg_OpenNaClExecutable,
     72                                     OnOpenNaClExecutable)
     73 #endif
     74     IPC_MESSAGE_UNHANDLED(handled = false)
     75   IPC_END_MESSAGE_MAP()
     76 
     77   return handled;
     78 }
     79 
     80 net::HostResolver* NaClHostMessageFilter::GetHostResolver() {
     81   return request_context_->GetURLRequestContext()->host_resolver();
     82 }
     83 
     84 #if !defined(DISABLE_NACL)
     85 void NaClHostMessageFilter::OnLaunchNaCl(
     86     const nacl::NaClLaunchParams& launch_params,
     87     IPC::Message* reply_msg) {
     88   NaClProcessHost* host = new NaClProcessHost(
     89       GURL(launch_params.manifest_url),
     90       launch_params.render_view_id,
     91       launch_params.permission_bits,
     92       launch_params.uses_irt,
     93       launch_params.enable_dyncode_syscalls,
     94       launch_params.enable_exception_handling,
     95       off_the_record_,
     96       profile_directory_);
     97   base::FilePath manifest_url =
     98       GetManifestPath(extension_info_map_.get(), launch_params.manifest_url);
     99   host->Launch(this, reply_msg, manifest_url);
    100 }
    101 
    102 void NaClHostMessageFilter::ReplyEnsurePnaclInstalled(
    103     int instance,
    104     bool success) {
    105   Send(new NaClViewMsg_EnsurePnaclInstalledReply(instance, success));
    106 }
    107 
    108 void NaClHostMessageFilter::SendProgressEnsurePnaclInstalled(
    109     int instance,
    110     const nacl::PnaclInstallProgress& progress) {
    111     // TODO(jvoung): actually send an IPC.
    112 }
    113 
    114 void NaClHostMessageFilter::OnEnsurePnaclInstalled(
    115     int instance) {
    116   nacl_file_host::EnsurePnaclInstalled(
    117       base::Bind(&NaClHostMessageFilter::ReplyEnsurePnaclInstalled,
    118                  this, instance),
    119       base::Bind(&NaClHostMessageFilter::SendProgressEnsurePnaclInstalled,
    120                  this, instance));
    121 }
    122 
    123 void NaClHostMessageFilter::OnGetReadonlyPnaclFd(
    124     const std::string& filename, IPC::Message* reply_msg) {
    125   // This posts a task to another thread, but the renderer will
    126   // block until the reply is sent.
    127   nacl_file_host::GetReadonlyPnaclFd(this, filename, reply_msg);
    128 
    129   // This is the first message we receive from the renderer once it knows we
    130   // want to use PNaCl, so start the translation cache initialization here.
    131   PnaclHost::GetInstance()->Init();
    132 }
    133 
    134 // Return the temporary file via a reply to the
    135 // NaClHostMsg_NaClCreateTemporaryFile sync message.
    136 void NaClHostMessageFilter::SyncReturnTemporaryFile(
    137     IPC::Message* reply_msg,
    138     base::PlatformFile fd) {
    139   if (fd == base::kInvalidPlatformFileValue) {
    140     reply_msg->set_reply_error();
    141   } else {
    142     NaClHostMsg_NaClCreateTemporaryFile::WriteReplyParams(
    143         reply_msg,
    144         IPC::GetFileHandleForProcess(fd, PeerHandle(), true));
    145   }
    146   Send(reply_msg);
    147 }
    148 
    149 void NaClHostMessageFilter::OnNaClCreateTemporaryFile(
    150     IPC::Message* reply_msg) {
    151   PnaclHost::GetInstance()->CreateTemporaryFile(
    152       base::Bind(&NaClHostMessageFilter::SyncReturnTemporaryFile,
    153                  this,
    154                  reply_msg));
    155 }
    156 
    157 void NaClHostMessageFilter::AsyncReturnTemporaryFile(
    158     int pp_instance,
    159     base::PlatformFile fd,
    160     bool is_hit) {
    161   Send(new NaClViewMsg_NexeTempFileReply(
    162       pp_instance,
    163       is_hit,
    164       // Don't close our copy of the handle, because PnaclHost will use it
    165       // when the translation finishes.
    166       IPC::GetFileHandleForProcess(fd, PeerHandle(), false)));
    167 }
    168 
    169 void NaClHostMessageFilter::OnGetNexeFd(
    170     int render_view_id,
    171     int pp_instance,
    172     const nacl::PnaclCacheInfo& cache_info) {
    173   if (!cache_info.pexe_url.is_valid()) {
    174     LOG(ERROR) << "Bad URL received from GetNexeFd: " <<
    175         cache_info.pexe_url.possibly_invalid_spec();
    176     BadMessageReceived();
    177     return;
    178   }
    179 
    180   PnaclHost::GetInstance()->GetNexeFd(
    181       render_process_id_,
    182       render_view_id,
    183       pp_instance,
    184       off_the_record_,
    185       cache_info,
    186       base::Bind(&NaClHostMessageFilter::AsyncReturnTemporaryFile,
    187                  this,
    188                  pp_instance));
    189 }
    190 
    191 void NaClHostMessageFilter::OnTranslationFinished(int instance, bool success) {
    192   PnaclHost::GetInstance()->TranslationFinished(
    193       render_process_id_, instance, success);
    194 }
    195 
    196 void NaClHostMessageFilter::OnNaClErrorStatus(int render_view_id,
    197                                               int error_id) {
    198   NaClBrowser::GetDelegate()->ShowNaClInfobar(render_process_id_,
    199                                               render_view_id, error_id);
    200 }
    201 
    202 void NaClHostMessageFilter::OnOpenNaClExecutable(int render_view_id,
    203                                                  const GURL& file_url,
    204                                                  IPC::Message* reply_msg) {
    205   nacl_file_host::OpenNaClExecutable(this, extension_info_map_,
    206                                      render_view_id, file_url, reply_msg);
    207 }
    208 #endif
    209