4e9225912ec83ef5cbfab2009f9d782d82343a77
[platform/framework/web/crosswalk.git] / src / components / nacl / renderer / pnacl_translation_resource_host.cc
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 }