nacl_host_message_filter.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "components/nacl/browser/nacl_host_message_filter.h"
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/sys_info.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/nacl/browser/nacl_browser.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/nacl/browser/nacl_file_host.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/nacl/browser/nacl_process_host.h"
11b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "components/nacl/browser/pnacl_host.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "components/nacl/common/nacl_host_messages.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ipc/ipc_platform_file.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_request_context.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "url/gurl.h"
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
18b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)namespace nacl {
19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
207dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochNaClHostMessageFilter::NaClHostMessageFilter(
21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int render_process_id,
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool is_off_the_record,
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::FilePath& profile_directory,
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    net::URLRequestContextGetter* request_context)
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : BrowserMessageFilter(NaClHostMsgStart),
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      render_process_id_(render_process_id),
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      off_the_record_(is_off_the_record),
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      profile_directory_(profile_directory),
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      request_context_(request_context),
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      weak_ptr_factory_(this) {
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochNaClHostMessageFilter::~NaClHostMessageFilter() {
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void NaClHostMessageFilter::OnChannelClosing() {
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pnacl::PnaclHost::GetInstance()->RendererClosing(render_process_id_);
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool NaClHostMessageFilter::OnMessageReceived(const IPC::Message& message,
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                              bool* message_was_ok) {
427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool handled = true;
437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP_EX(NaClHostMessageFilter, message, *message_was_ok)
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if !defined(DISABLE_NACL)
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClHostMsg_LaunchNaCl, OnLaunchNaCl)
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClHostMsg_GetReadonlyPnaclFD,
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                    OnGetReadonlyPnaclFd)
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClHostMsg_NaClCreateTemporaryFile,
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                    OnNaClCreateTemporaryFile)
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    IPC_MESSAGE_HANDLER(NaClHostMsg_NexeTempFileRequest,
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                        OnGetNexeFd)
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    IPC_MESSAGE_HANDLER(NaClHostMsg_ReportTranslationFinished,
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                        OnTranslationFinished)
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    IPC_MESSAGE_HANDLER(NaClHostMsg_MissingArchError,
55b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                        OnMissingArchError)
56b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClHostMsg_OpenNaClExecutable,
57b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                    OnOpenNaClExecutable)
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    IPC_MESSAGE_HANDLER(NaClHostMsg_NaClGetNumProcessors,
59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                        OnNaClGetNumProcessors)
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  IPC_END_MESSAGE_MAP()
636d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
646d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  return handled;
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)net::HostResolver* NaClHostMessageFilter::GetHostResolver() {
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return request_context_->GetURLRequestContext()->host_resolver();
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if !defined(DISABLE_NACL)
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void NaClHostMessageFilter::OnLaunchNaCl(
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const nacl::NaClLaunchParams& launch_params,
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    IPC::Message* reply_msg) {
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NaClProcessHost* host = new NaClProcessHost(
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      GURL(launch_params.manifest_url),
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      launch_params.render_view_id,
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      launch_params.permission_bits,
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      launch_params.uses_irt,
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      launch_params.uses_nonsfi_mode,
817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      launch_params.enable_dyncode_syscalls,
827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      launch_params.enable_exception_handling,
837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      launch_params.enable_crash_throttling,
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      off_the_record_,
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      profile_directory_);
86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  GURL manifest_url(launch_params.manifest_url);
87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::FilePath manifest_path;
88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // We're calling MapUrlToLocalFilePath with the non-blocking API
894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // because we're running in the I/O thread. Ideally we'd use the other path,
904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // which would cover more cases.
914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  nacl::NaClBrowser::GetDelegate()->MapUrlToLocalFilePath(
927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      manifest_url, false /* use_blocking_api */, &manifest_path);
937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  host->Launch(this, reply_msg, manifest_path);
94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void NaClHostMessageFilter::OnGetReadonlyPnaclFd(
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& filename, IPC::Message* reply_msg) {
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // This posts a task to another thread, but the renderer will
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // block until the reply is sent.
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  nacl_file_host::GetReadonlyPnaclFd(this, filename, reply_msg);
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // This is the first message we receive from the renderer once it knows we
103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // want to use PNaCl, so start the translation cache initialization here.
104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  pnacl::PnaclHost::GetInstance()->Init();
105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Return the temporary file via a reply to the
1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// NaClHostMsg_NaClCreateTemporaryFile sync message.
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NaClHostMessageFilter::SyncReturnTemporaryFile(
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC::Message* reply_msg,
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::File file) {
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (file.IsValid()) {
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    NaClHostMsg_NaClCreateTemporaryFile::WriteReplyParams(
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        reply_msg,
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        IPC::TakeFileHandleForProcess(file.Pass(), PeerHandle()));
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    reply_msg->set_reply_error();
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Send(reply_msg);
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NaClHostMessageFilter::OnNaClCreateTemporaryFile(
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC::Message* reply_msg) {
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  pnacl::PnaclHost::GetInstance()->CreateTemporaryFile(
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&NaClHostMessageFilter::SyncReturnTemporaryFile,
126                 this,
127                 reply_msg));
128}
129
130void NaClHostMessageFilter::AsyncReturnTemporaryFile(
131    int pp_instance,
132    base::PlatformFile fd,
133    bool is_hit) {
134  Send(new NaClViewMsg_NexeTempFileReply(
135      pp_instance,
136      is_hit,
137      // Don't close our copy of the handle, because PnaclHost will use it
138      // when the translation finishes.
139      IPC::GetFileHandleForProcess(fd, PeerHandle(), false)));
140}
141
142void NaClHostMessageFilter::OnNaClGetNumProcessors(int* num_processors) {
143  *num_processors = base::SysInfo::NumberOfProcessors();
144}
145
146void NaClHostMessageFilter::OnGetNexeFd(
147    int render_view_id,
148    int pp_instance,
149    const nacl::PnaclCacheInfo& cache_info) {
150  if (!cache_info.pexe_url.is_valid()) {
151    LOG(ERROR) << "Bad URL received from GetNexeFd: " <<
152        cache_info.pexe_url.possibly_invalid_spec();
153    BadMessageReceived();
154    return;
155  }
156
157  pnacl::PnaclHost::GetInstance()->GetNexeFd(
158      render_process_id_,
159      render_view_id,
160      pp_instance,
161      off_the_record_,
162      cache_info,
163      base::Bind(&NaClHostMessageFilter::AsyncReturnTemporaryFile,
164                 this,
165                 pp_instance));
166}
167
168void NaClHostMessageFilter::OnTranslationFinished(int instance, bool success) {
169  pnacl::PnaclHost::GetInstance()->TranslationFinished(
170      render_process_id_, instance, success);
171}
172
173void NaClHostMessageFilter::OnMissingArchError(int render_view_id) {
174  nacl::NaClBrowser::GetDelegate()->
175      ShowMissingArchInfobar(render_process_id_, render_view_id);
176}
177
178void NaClHostMessageFilter::OnOpenNaClExecutable(int render_view_id,
179                                                 const GURL& file_url,
180                                                 IPC::Message* reply_msg) {
181  nacl_file_host::OpenNaClExecutable(this, render_view_id, file_url,
182                                     reply_msg);
183}
184#endif
185
186}  // namespace nacl
187