Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 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 | #ifndef DISABLE_NACL |
Ben Murdoch | a3f7b4e | 2013-07-24 10:36:34 +0100 | [diff] [blame] | 8 | #include "components/nacl/common/nacl_host_messages.h" |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 9 | #include "ppapi/c/pp_errors.h" |
| 10 | #include "ppapi/shared_impl/ppapi_globals.h" |
| 11 | |
| 12 | using ppapi::TrackedCallback; |
| 13 | using ppapi::PpapiGlobals; |
| 14 | |
| 15 | PnaclTranslationResourceHost::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 | |
| 21 | PnaclTranslationResourceHost::CacheRequestInfo::~CacheRequestInfo() {} |
| 22 | |
| 23 | PnaclTranslationResourceHost::PnaclTranslationResourceHost( |
| 24 | const scoped_refptr<base::MessageLoopProxy>& io_message_loop) |
| 25 | : io_message_loop_(io_message_loop), channel_(NULL) {} |
| 26 | |
| 27 | PnaclTranslationResourceHost::~PnaclTranslationResourceHost() { |
Ben Murdoch | 2385ea3 | 2013-08-06 11:01:04 +0100 | [diff] [blame] | 28 | DCHECK(io_message_loop_->BelongsToCurrentThread()); |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 29 | CleanupCacheRequests(); |
Ben Murdoch | 2385ea3 | 2013-08-06 11:01:04 +0100 | [diff] [blame] | 30 | CleanupEnsurePnaclRequests(); |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 31 | } |
| 32 | |
| 33 | void PnaclTranslationResourceHost::OnFilterAdded(IPC::Channel* channel) { |
| 34 | DCHECK(io_message_loop_->BelongsToCurrentThread()); |
| 35 | channel_ = channel; |
| 36 | } |
| 37 | |
| 38 | void PnaclTranslationResourceHost::OnFilterRemoved() { |
| 39 | DCHECK(io_message_loop_->BelongsToCurrentThread()); |
| 40 | channel_ = NULL; |
| 41 | } |
| 42 | |
| 43 | void PnaclTranslationResourceHost::OnChannelClosing() { |
| 44 | DCHECK(io_message_loop_->BelongsToCurrentThread()); |
| 45 | channel_ = NULL; |
| 46 | } |
| 47 | |
| 48 | bool 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 Murdoch | 2385ea3 | 2013-08-06 11:01:04 +0100 | [diff] [blame] | 54 | IPC_MESSAGE_HANDLER(NaClViewMsg_EnsurePnaclInstalledReply, |
| 55 | OnEnsurePnaclInstalledReply) |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 56 | IPC_MESSAGE_UNHANDLED(handled = false) |
| 57 | IPC_END_MESSAGE_MAP() |
| 58 | return handled; |
| 59 | } |
| 60 | |
| 61 | void PnaclTranslationResourceHost::RequestNexeFd( |
| 62 | int render_view_id, |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 63 | PP_Instance instance, |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 64 | const nacl::PnaclCacheInfo& cache_info, |
| 65 | PP_Bool* is_hit, |
| 66 | PP_FileHandle* file_handle, |
| 67 | scoped_refptr<TrackedCallback> callback) { |
Ben Murdoch | 2385ea3 | 2013-08-06 11:01:04 +0100 | [diff] [blame] | 68 | 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 Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 82 | |
Ben Murdoch | 2385ea3 | 2013-08-06 11:01:04 +0100 | [diff] [blame] | 83 | void 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 Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 91 | if (!channel_ || !channel_->Send(new NaClHostMsg_NexeTempFileRequest( |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 92 | render_view_id, instance, cache_info))) { |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 93 | 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 Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 101 | instance, CacheRequestInfo(is_hit, file_handle, callback))); |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 102 | } |
| 103 | |
| 104 | void PnaclTranslationResourceHost::ReportTranslationFinished( |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 105 | PP_Instance instance, |
| 106 | PP_Bool success) { |
Ben Murdoch | 2385ea3 | 2013-08-06 11:01:04 +0100 | [diff] [blame] | 107 | DCHECK(PpapiGlobals::Get()-> |
| 108 | GetMainThreadMessageLoop()->BelongsToCurrentThread()); |
| 109 | io_message_loop_->PostTask( |
| 110 | FROM_HERE, |
| 111 | base::Bind(&PnaclTranslationResourceHost::SendReportTranslationFinished, |
| 112 | this, |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 113 | instance, |
| 114 | success)); |
Ben Murdoch | 2385ea3 | 2013-08-06 11:01:04 +0100 | [diff] [blame] | 115 | return; |
| 116 | } |
| 117 | |
| 118 | void PnaclTranslationResourceHost::SendReportTranslationFinished( |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 119 | PP_Instance instance, |
| 120 | PP_Bool success) { |
Ben Murdoch | 2385ea3 | 2013-08-06 11:01:04 +0100 | [diff] [blame] | 121 | DCHECK(io_message_loop_->BelongsToCurrentThread()); |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 122 | // 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 Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 126 | DCHECK(pending_cache_requests_.count(instance) == 0); |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 127 | channel_->Send(new NaClHostMsg_ReportTranslationFinished(instance, |
| 128 | PP_ToBool(success))); |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 129 | } |
| 130 | |
| 131 | void PnaclTranslationResourceHost::OnNexeTempFileReply( |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 132 | PP_Instance instance, |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 133 | bool is_hit, |
| 134 | IPC::PlatformFileForTransit file) { |
Ben Murdoch | 2385ea3 | 2013-08-06 11:01:04 +0100 | [diff] [blame] | 135 | DCHECK(io_message_loop_->BelongsToCurrentThread()); |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 136 | CacheRequestInfoMap::iterator it = pending_cache_requests_.find(instance); |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 137 | 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 | |
| 161 | void PnaclTranslationResourceHost::CleanupCacheRequests() { |
Ben Murdoch | 2385ea3 | 2013-08-06 11:01:04 +0100 | [diff] [blame] | 162 | DCHECK(io_message_loop_->BelongsToCurrentThread()); |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 163 | 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 Murdoch | 2385ea3 | 2013-08-06 11:01:04 +0100 | [diff] [blame] | 171 | void 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 | |
| 183 | void 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 | |
| 206 | void 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 | |
| 226 | void 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 Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 237 | #endif // DISABLE_NACL |