blob: 609ddecf3ba24a8cf1d47a10ba7e422d5f988e04 [file] [log] [blame]
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01001// 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#ifndef DISABLE_NACL
Ben Murdocha3f7b4e2013-07-24 10:36:34 +01008#include "components/nacl/common/nacl_host_messages.h"
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01009#include "ppapi/c/pp_errors.h"
10#include "ppapi/shared_impl/ppapi_globals.h"
11
12using ppapi::TrackedCallback;
13using ppapi::PpapiGlobals;
14
15PnaclTranslationResourceHost::CacheRequestInfo::CacheRequestInfo(
16 PP_Bool* hit,
17 PP_FileHandle* handle,
18 scoped_refptr<TrackedCallback> cb)
19 : is_hit(hit), file_handle(handle), callback(cb) {}
20
21PnaclTranslationResourceHost::CacheRequestInfo::~CacheRequestInfo() {}
22
23PnaclTranslationResourceHost::PnaclTranslationResourceHost(
24 const scoped_refptr<base::MessageLoopProxy>& io_message_loop)
25 : io_message_loop_(io_message_loop), channel_(NULL) {}
26
27PnaclTranslationResourceHost::~PnaclTranslationResourceHost() {
Ben Murdoch2385ea32013-08-06 11:01:04 +010028 DCHECK(io_message_loop_->BelongsToCurrentThread());
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010029 CleanupCacheRequests();
Ben Murdoch2385ea32013-08-06 11:01:04 +010030 CleanupEnsurePnaclRequests();
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010031}
32
33void PnaclTranslationResourceHost::OnFilterAdded(IPC::Channel* channel) {
34 DCHECK(io_message_loop_->BelongsToCurrentThread());
35 channel_ = channel;
36}
37
38void PnaclTranslationResourceHost::OnFilterRemoved() {
39 DCHECK(io_message_loop_->BelongsToCurrentThread());
40 channel_ = NULL;
41}
42
43void PnaclTranslationResourceHost::OnChannelClosing() {
44 DCHECK(io_message_loop_->BelongsToCurrentThread());
45 channel_ = NULL;
46}
47
48bool PnaclTranslationResourceHost::OnMessageReceived(
49 const IPC::Message& message) {
50 DCHECK(io_message_loop_->BelongsToCurrentThread());
51 bool handled = true;
52 IPC_BEGIN_MESSAGE_MAP(PnaclTranslationResourceHost, message)
53 IPC_MESSAGE_HANDLER(NaClViewMsg_NexeTempFileReply, OnNexeTempFileReply)
Ben Murdoch2385ea32013-08-06 11:01:04 +010054 IPC_MESSAGE_HANDLER(NaClViewMsg_EnsurePnaclInstalledReply,
55 OnEnsurePnaclInstalledReply)
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010056 IPC_MESSAGE_UNHANDLED(handled = false)
57 IPC_END_MESSAGE_MAP()
58 return handled;
59}
60
61void PnaclTranslationResourceHost::RequestNexeFd(
62 int render_view_id,
Ben Murdochca12bfa2013-07-23 11:17:05 +010063 PP_Instance instance,
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010064 const nacl::PnaclCacheInfo& cache_info,
65 PP_Bool* is_hit,
66 PP_FileHandle* file_handle,
67 scoped_refptr<TrackedCallback> callback) {
Ben Murdoch2385ea32013-08-06 11:01:04 +010068 DCHECK(PpapiGlobals::Get()->
69 GetMainThreadMessageLoop()->BelongsToCurrentThread());
70 io_message_loop_->PostTask(
71 FROM_HERE,
72 base::Bind(&PnaclTranslationResourceHost::SendRequestNexeFd,
73 this,
74 render_view_id,
75 instance,
76 cache_info,
77 is_hit,
78 file_handle,
79 callback));
80 return;
81}
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010082
Ben Murdoch2385ea32013-08-06 11:01:04 +010083void PnaclTranslationResourceHost::SendRequestNexeFd(
84 int render_view_id,
85 PP_Instance instance,
86 const nacl::PnaclCacheInfo& cache_info,
87 PP_Bool* is_hit,
88 PP_FileHandle* file_handle,
89 scoped_refptr<TrackedCallback> callback) {
90 DCHECK(io_message_loop_->BelongsToCurrentThread());
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010091 if (!channel_ || !channel_->Send(new NaClHostMsg_NexeTempFileRequest(
Ben Murdochca12bfa2013-07-23 11:17:05 +010092 render_view_id, instance, cache_info))) {
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010093 PpapiGlobals::Get()->GetMainThreadMessageLoop()
94 ->PostTask(FROM_HERE,
95 base::Bind(&TrackedCallback::Run,
96 callback,
97 static_cast<int32_t>(PP_ERROR_FAILED)));
98 return;
99 }
100 pending_cache_requests_.insert(std::make_pair(
Ben Murdochca12bfa2013-07-23 11:17:05 +0100101 instance, CacheRequestInfo(is_hit, file_handle, callback)));
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100102}
103
104void PnaclTranslationResourceHost::ReportTranslationFinished(
Ben Murdochbb1529c2013-08-08 10:24:53 +0100105 PP_Instance instance,
106 PP_Bool success) {
Ben Murdoch2385ea32013-08-06 11:01:04 +0100107 DCHECK(PpapiGlobals::Get()->
108 GetMainThreadMessageLoop()->BelongsToCurrentThread());
109 io_message_loop_->PostTask(
110 FROM_HERE,
111 base::Bind(&PnaclTranslationResourceHost::SendReportTranslationFinished,
112 this,
Ben Murdochbb1529c2013-08-08 10:24:53 +0100113 instance,
114 success));
Ben Murdoch2385ea32013-08-06 11:01:04 +0100115 return;
116}
117
118void PnaclTranslationResourceHost::SendReportTranslationFinished(
Ben Murdochbb1529c2013-08-08 10:24:53 +0100119 PP_Instance instance,
120 PP_Bool success) {
Ben Murdoch2385ea32013-08-06 11:01:04 +0100121 DCHECK(io_message_loop_->BelongsToCurrentThread());
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100122 // If the channel is closed or we have been detached, we are probably shutting
123 // down, so just don't send anything.
124 if (!channel_)
125 return;
Ben Murdochca12bfa2013-07-23 11:17:05 +0100126 DCHECK(pending_cache_requests_.count(instance) == 0);
Ben Murdochbb1529c2013-08-08 10:24:53 +0100127 channel_->Send(new NaClHostMsg_ReportTranslationFinished(instance,
128 PP_ToBool(success)));
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100129}
130
131void PnaclTranslationResourceHost::OnNexeTempFileReply(
Ben Murdochca12bfa2013-07-23 11:17:05 +0100132 PP_Instance instance,
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100133 bool is_hit,
134 IPC::PlatformFileForTransit file) {
Ben Murdoch2385ea32013-08-06 11:01:04 +0100135 DCHECK(io_message_loop_->BelongsToCurrentThread());
Ben Murdochca12bfa2013-07-23 11:17:05 +0100136 CacheRequestInfoMap::iterator it = pending_cache_requests_.find(instance);
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100137 int32_t status = PP_ERROR_FAILED;
138 // Handle the expected successful case first.
139 if (it != pending_cache_requests_.end() &&
140 !(file == IPC::InvalidPlatformFileForTransit()) &&
141 TrackedCallback::IsPending(it->second.callback)) {
142 *it->second.is_hit = PP_FromBool(is_hit);
143 *it->second.file_handle = IPC::PlatformFileForTransitToPlatformFile(file);
144 status = PP_OK;
145 }
146 if (it == pending_cache_requests_.end()) {
147 DLOG(ERROR) << "Could not find pending request for reply";
148 } else {
149 PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask(
150 FROM_HERE,
151 base::Bind(&TrackedCallback::Run, it->second.callback, status));
152 pending_cache_requests_.erase(it);
153 }
154 if (file == IPC::InvalidPlatformFileForTransit()) {
155 DLOG(ERROR) << "Got invalid platformfilefortransit";
156 } else if (status != PP_OK) {
157 base::ClosePlatformFile(IPC::PlatformFileForTransitToPlatformFile(file));
158 }
159}
160
161void PnaclTranslationResourceHost::CleanupCacheRequests() {
Ben Murdoch2385ea32013-08-06 11:01:04 +0100162 DCHECK(io_message_loop_->BelongsToCurrentThread());
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100163 for (CacheRequestInfoMap::iterator it = pending_cache_requests_.begin();
164 it != pending_cache_requests_.end();
165 ++it) {
166 it->second.callback->PostAbort();
167 }
168 pending_cache_requests_.clear();
169}
170
Ben Murdoch2385ea32013-08-06 11:01:04 +0100171void PnaclTranslationResourceHost::EnsurePnaclInstalled(
172 PP_Instance instance,
173 scoped_refptr<TrackedCallback> callback) {
174 DCHECK(PpapiGlobals::Get()->
175 GetMainThreadMessageLoop()->BelongsToCurrentThread());
176 io_message_loop_->PostTask(
177 FROM_HERE,
178 base::Bind(&PnaclTranslationResourceHost::SendEnsurePnaclInstalled,
179 this, instance, callback));
180 return;
181}
182
183void PnaclTranslationResourceHost::SendEnsurePnaclInstalled(
184 PP_Instance instance,
185 scoped_refptr<TrackedCallback> callback) {
186 DCHECK(io_message_loop_->BelongsToCurrentThread());
187 // If a request is already in, just queue this one and wait for notification.
188 // Hope that the request is not canceled.
189 if (pending_ensure_pnacl_requests_.size() > 0) {
190 pending_ensure_pnacl_requests_.push_back(callback);
191 return;
192 }
193 // Otherwise, try to send the request, then queue.
194 if (!channel_ || !channel_->Send(new NaClHostMsg_EnsurePnaclInstalled(
195 instance))) {
196 PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask(
197 FROM_HERE,
198 base::Bind(&TrackedCallback::Run,
199 callback,
200 static_cast<int32_t>(PP_ERROR_FAILED)));
201 return;
202 }
203 pending_ensure_pnacl_requests_.push_back(callback);
204}
205
206void PnaclTranslationResourceHost::OnEnsurePnaclInstalledReply(
207 PP_Instance instance,
208 bool success) {
209 DCHECK(io_message_loop_->BelongsToCurrentThread());
210 // Broadcast to all listeners.
211 for (EnsurePnaclInstalledList::iterator
212 i = pending_ensure_pnacl_requests_.begin(),
213 e = pending_ensure_pnacl_requests_.end();
214 i != e; ++i) {
215 if (TrackedCallback::IsPending(*i)) {
216 PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask(
217 FROM_HERE,
218 base::Bind(&TrackedCallback::Run,
219 *i,
220 static_cast<int32_t>(success ? PP_OK : PP_ERROR_FAILED)));
221 }
222 }
223 pending_ensure_pnacl_requests_.clear();
224}
225
226void PnaclTranslationResourceHost::CleanupEnsurePnaclRequests() {
227 DCHECK(io_message_loop_->BelongsToCurrentThread());
228 for (EnsurePnaclInstalledList::iterator
229 i = pending_ensure_pnacl_requests_.begin(),
230 e = pending_ensure_pnacl_requests_.end();
231 i != e; ++i) {
232 (*i)->PostAbort();
233 }
234 pending_ensure_pnacl_requests_.clear();
235}
236
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100237#endif // DISABLE_NACL