Home | History | Annotate | Download | only in renderer
      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 "pnacl_translation_resource_host.h"
      6 
      7 #include "components/nacl/common/nacl_host_messages.h"
      8 #include "ppapi/c/pp_errors.h"
      9 #include "ppapi/shared_impl/ppapi_globals.h"
     10 
     11 using ppapi::PpapiGlobals;
     12 
     13 PnaclTranslationResourceHost::PnaclTranslationResourceHost(
     14     const scoped_refptr<base::MessageLoopProxy>& io_message_loop)
     15     : io_message_loop_(io_message_loop), sender_(NULL) {}
     16 
     17 PnaclTranslationResourceHost::~PnaclTranslationResourceHost() {
     18   DCHECK(io_message_loop_->BelongsToCurrentThread());
     19   CleanupCacheRequests();
     20 }
     21 
     22 void PnaclTranslationResourceHost::OnFilterAdded(IPC::Sender* sender) {
     23   DCHECK(io_message_loop_->BelongsToCurrentThread());
     24   sender_ = sender;
     25 }
     26 
     27 void PnaclTranslationResourceHost::OnFilterRemoved() {
     28   DCHECK(io_message_loop_->BelongsToCurrentThread());
     29   sender_ = NULL;
     30 }
     31 
     32 void PnaclTranslationResourceHost::OnChannelClosing() {
     33   DCHECK(io_message_loop_->BelongsToCurrentThread());
     34   sender_ = NULL;
     35 }
     36 
     37 bool PnaclTranslationResourceHost::OnMessageReceived(
     38     const IPC::Message& message) {
     39   DCHECK(io_message_loop_->BelongsToCurrentThread());
     40   bool handled = true;
     41   IPC_BEGIN_MESSAGE_MAP(PnaclTranslationResourceHost, message)
     42     IPC_MESSAGE_HANDLER(NaClViewMsg_NexeTempFileReply, OnNexeTempFileReply)
     43     IPC_MESSAGE_UNHANDLED(handled = false)
     44   IPC_END_MESSAGE_MAP()
     45   return handled;
     46 }
     47 
     48 void PnaclTranslationResourceHost::RequestNexeFd(
     49     int render_view_id,
     50     PP_Instance instance,
     51     const nacl::PnaclCacheInfo& cache_info,
     52     RequestNexeFdCallback callback) {
     53   DCHECK(PpapiGlobals::Get()->
     54          GetMainThreadMessageLoop()->BelongsToCurrentThread());
     55   io_message_loop_->PostTask(
     56       FROM_HERE,
     57       base::Bind(&PnaclTranslationResourceHost::SendRequestNexeFd,
     58                  this,
     59                  render_view_id,
     60                  instance,
     61                  cache_info,
     62                  callback));
     63   return;
     64 }
     65 
     66 void PnaclTranslationResourceHost::SendRequestNexeFd(
     67     int render_view_id,
     68     PP_Instance instance,
     69     const nacl::PnaclCacheInfo& cache_info,
     70     RequestNexeFdCallback callback) {
     71   DCHECK(io_message_loop_->BelongsToCurrentThread());
     72   if (!sender_ || !sender_->Send(new NaClHostMsg_NexeTempFileRequest(
     73           render_view_id, instance, cache_info))) {
     74     PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask(
     75         FROM_HERE,
     76         base::Bind(callback,
     77                    static_cast<int32_t>(PP_ERROR_FAILED),
     78                    false,
     79                    PP_kInvalidFileHandle));
     80     return;
     81   }
     82   pending_cache_requests_.insert(std::make_pair(instance, callback));
     83 }
     84 
     85 void PnaclTranslationResourceHost::ReportTranslationFinished(
     86     PP_Instance instance,
     87     PP_Bool success) {
     88   DCHECK(PpapiGlobals::Get()->
     89          GetMainThreadMessageLoop()->BelongsToCurrentThread());
     90   io_message_loop_->PostTask(
     91       FROM_HERE,
     92       base::Bind(&PnaclTranslationResourceHost::SendReportTranslationFinished,
     93                  this,
     94                  instance,
     95                  success));
     96   return;
     97 }
     98 
     99 void PnaclTranslationResourceHost::SendReportTranslationFinished(
    100     PP_Instance instance,
    101     PP_Bool success) {
    102   DCHECK(io_message_loop_->BelongsToCurrentThread());
    103   // If the sender is closed or we have been detached, we are probably shutting
    104   // down, so just don't send anything.
    105   if (!sender_)
    106     return;
    107   DCHECK(pending_cache_requests_.count(instance) == 0);
    108   sender_->Send(new NaClHostMsg_ReportTranslationFinished(instance,
    109                                                           PP_ToBool(success)));
    110 }
    111 
    112 void PnaclTranslationResourceHost::OnNexeTempFileReply(
    113     PP_Instance instance,
    114     bool is_hit,
    115     IPC::PlatformFileForTransit file) {
    116   DCHECK(io_message_loop_->BelongsToCurrentThread());
    117   base::File base_file = IPC::PlatformFileForTransitToFile(file);
    118   CacheRequestInfoMap::iterator it = pending_cache_requests_.find(instance);
    119   int32_t status = PP_ERROR_FAILED;
    120   // Handle the expected successful case first.
    121   PP_FileHandle file_handle = PP_kInvalidFileHandle;
    122   if (it != pending_cache_requests_.end() && base_file.IsValid()) {
    123     file_handle = base_file.TakePlatformFile();
    124     status = PP_OK;
    125   }
    126   if (it == pending_cache_requests_.end()) {
    127     DLOG(ERROR) << "Could not find pending request for reply";
    128   } else {
    129     PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask(
    130         FROM_HERE,
    131         base::Bind(it->second, status, is_hit, file_handle));
    132     pending_cache_requests_.erase(it);
    133   }
    134   if (!base_file.IsValid()) {
    135     DLOG(ERROR) << "Got invalid platformfilefortransit";
    136   }
    137 }
    138 
    139 void PnaclTranslationResourceHost::CleanupCacheRequests() {
    140   DCHECK(io_message_loop_->BelongsToCurrentThread());
    141   for (CacheRequestInfoMap::iterator it = pending_cache_requests_.begin();
    142        it != pending_cache_requests_.end();
    143        ++it) {
    144     PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask(
    145         FROM_HERE,
    146         base::Bind(it->second,
    147                    static_cast<int32_t>(PP_ERROR_ABORTED),
    148                    false,
    149                    PP_kInvalidFileHandle));
    150   }
    151   pending_cache_requests_.clear();
    152 }
    153