15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/renderer/pepper/ppb_nacl_private_impl.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef DISABLE_NACL
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/rand_util.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/renderer/chrome_render_process_observer.h"
157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/renderer/pepper/pnacl_translation_resource_host.h"
16a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "components/nacl/common/nacl_host_messages.h"
17a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "components/nacl/common/nacl_types.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_client.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_switches.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/sandbox_init.h"
2158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "content/public/renderer/pepper_plugin_instance.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/renderer/renderer_ppapi_host.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/renderer/render_thread.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/renderer/render_view.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_bool.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/private/pp_file_handle.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/native_client/src/trusted/plugin/nacl_entry_points.h"
28a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "ppapi/shared_impl/ppapi_permissions.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/ppapi_preferences.h"
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ppapi/shared_impl/var.h"
31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ppapi/thunk/enter.h"
327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebDocument.h"
337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebElement.h"
347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebFrame.h"
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebPluginContainer.h"
367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebView.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbase::LazyInstance<scoped_refptr<PnaclTranslationResourceHost> >
417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    g_pnacl_resource_host = LAZY_INSTANCE_INITIALIZER;
427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstatic bool InitializePnaclResourceHost() {
442385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // Must run on the main thread.
452385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  content::RenderThread* render_thread = content::RenderThread::Get();
462385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (!render_thread)
472385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return false;
487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!g_pnacl_resource_host.Get()) {
497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    g_pnacl_resource_host.Get() = new PnaclTranslationResourceHost(
507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        render_thread->GetIOMessageLoopProxy());
517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    render_thread->AddFilter(g_pnacl_resource_host.Get());
527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return true;
547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct InstanceInfo {
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InstanceInfo() : plugin_pid(base::kNullProcessId), plugin_child_id(0) {}
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ppapi::PpapiPermissions permissions;
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ProcessId plugin_pid;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int plugin_child_id;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC::ChannelHandle channel_handle;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef std::map<PP_Instance, InstanceInfo> InstanceInfoMap;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::LazyInstance<InstanceInfoMap> g_instance_info =
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LAZY_INSTANCE_INITIALIZER;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static int GetRoutingID(PP_Instance instance) {
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check that we are on the main renderer thread.
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(content::RenderThread::Get());
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::RendererPpapiHost *host =
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::RendererPpapiHost::GetForPPInstance(instance);
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!host)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return 0;
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return host->GetRoutingIDForWidget(instance);
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Launch NaCl's sel_ldr process.
81a3f7b4e666c476898878fa745f637129375cd889Ben MurdochPP_ExternalPluginResult LaunchSelLdr(PP_Instance instance,
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const char* alleged_url,
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           PP_Bool uses_irt,
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           PP_Bool uses_ppapi,
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           PP_Bool enable_ppapi_dev,
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                           PP_Bool enable_dyncode_syscalls,
877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           PP_Bool enable_exception_handling,
88ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                           void* imc_handle,
89ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                           struct PP_Var* error_message) {
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  nacl::FileDescriptor result_socket;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC::Sender* sender = content::RenderThread::Get();
927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(sender);
93ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  *error_message = PP_MakeUndefined();
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int routing_id = 0;
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If the nexe uses ppapi APIs, we need a routing ID.
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // To get the routing ID, we must be on the main thread.
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Some nexes do not use ppapi and launch from the background thread,
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // so those nexes can skip finding a routing_id.
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (uses_ppapi) {
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    routing_id = GetRoutingID(instance);
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!routing_id)
102a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      return PP_EXTERNAL_PLUGIN_FAILED;
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InstanceInfo instance_info;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  instance_info.url = GURL(alleged_url);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32_t perm_bits = ppapi::PERMISSION_NONE;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Conditionally block 'Dev' interfaces. We do this for the NaCl process, so
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it's clearer to developers when they are using 'Dev' inappropriately. We
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // must also check on the trusted side of the proxy.
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (enable_ppapi_dev)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    perm_bits |= ppapi::PERMISSION_DEV;
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  instance_info.permissions =
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ppapi::PpapiPermissions::GetForCommandLine(perm_bits);
116ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  std::string error_message_string;
117ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  nacl::NaClLaunchResult launch_result;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!sender->Send(new NaClHostMsg_LaunchNaCl(
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          nacl::NaClLaunchParams(instance_info.url.spec(),
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 routing_id,
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 perm_bits,
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 PP_ToBool(uses_irt),
1247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                 PP_ToBool(enable_dyncode_syscalls),
1257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                 PP_ToBool(enable_exception_handling)),
126ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch          &launch_result,
127ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch          &error_message_string))) {
128a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    return PP_EXTERNAL_PLUGIN_FAILED;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
130ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!error_message_string.empty()) {
131ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    *error_message = ppapi::StringVar::StringToPPVar(error_message_string);
132a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    return PP_EXTERNAL_PLUGIN_FAILED;
133ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
134ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  result_socket = launch_result.imc_channel_handle;
135ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  instance_info.channel_handle = launch_result.ipc_channel_handle;
136ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  instance_info.plugin_pid = launch_result.plugin_pid;
137ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  instance_info.plugin_child_id = launch_result.plugin_child_id;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Don't save instance_info if channel handle is invalid.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool invalid_handle = instance_info.channel_handle.name.empty();
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!invalid_handle)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    invalid_handle = (instance_info.channel_handle.socket.fd == -1);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!invalid_handle)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_instance_info.Get()[instance] = instance_info;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *(static_cast<NaClHandle*>(imc_handle)) =
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      nacl::ToNativeHandle(result_socket);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
150a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  return PP_EXTERNAL_PLUGIN_OK;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
153a3f7b4e666c476898878fa745f637129375cd889Ben MurdochPP_ExternalPluginResult StartPpapiProxy(PP_Instance instance) {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InstanceInfoMap& map = g_instance_info.Get();
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InstanceInfoMap::iterator it = map.find(instance);
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (it == map.end()) {
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DLOG(ERROR) << "Could not find instance ID";
158a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    return PP_EXTERNAL_PLUGIN_FAILED;
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InstanceInfo instance_info = it->second;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map.erase(it);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  content::PepperPluginInstance* plugin_instance =
16458e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch      content::PepperPluginInstance::Get(instance);
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!plugin_instance) {
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DLOG(ERROR) << "GetInstance() failed";
167a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    return PP_EXTERNAL_PLUGIN_ERROR_MODULE;
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
170a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  return plugin_instance->SwitchToOutOfProcessProxy(
171a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      base::FilePath().AppendASCII(instance_info.url.spec()),
172a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      instance_info.permissions,
173a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      instance_info.channel_handle,
174a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      instance_info.plugin_pid,
175a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      instance_info.plugin_child_id);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int UrandomFD(void) {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base::GetUrandomFD();
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return -1;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PP_Bool Are3DInterfacesDisabled() {
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return PP_FromBool(CommandLine::ForCurrentProcess()->HasSwitch(
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         switches::kDisable3DAPIs));
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t BrokerDuplicateHandle(PP_FileHandle source_handle,
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              uint32_t process_id,
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              PP_FileHandle* target_handle,
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              uint32_t desired_access,
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              uint32_t options) {
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return content::BrokerDuplicateHandle(source_handle, process_id,
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        target_handle, desired_access,
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        options);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2052385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochint32_t EnsurePnaclInstalled(PP_Instance instance,
2062385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                             PP_CompletionCallback callback) {
2072385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  ppapi::thunk::EnterInstance enter(instance, callback);
2082385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (enter.failed())
2092385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return enter.retval();
2102385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (!InitializePnaclResourceHost())
2112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return enter.SetResult(PP_ERROR_FAILED);
2122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  g_pnacl_resource_host.Get()->EnsurePnaclInstalled(
2132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      instance,
2142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      enter.callback());
2152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return enter.SetResult(PP_OK_COMPLETIONPENDING);
2162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
2172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_FileHandle GetReadonlyPnaclFD(const char* filename) {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC::PlatformFileForTransit out_fd = IPC::InvalidPlatformFileForTransit();
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC::Sender* sender = content::RenderThread::Get();
2217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(sender);
2227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!sender->Send(new NaClHostMsg_GetReadonlyPnaclFD(
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          std::string(filename),
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &out_fd))) {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return base::kInvalidPlatformFileValue;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (out_fd == IPC::InvalidPlatformFileForTransit()) {
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return base::kInvalidPlatformFileValue;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::PlatformFile handle =
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IPC::PlatformFileForTransitToPlatformFile(out_fd);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return handle;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_FileHandle CreateTemporaryFile(PP_Instance instance) {
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC::PlatformFileForTransit transit_fd = IPC::InvalidPlatformFileForTransit();
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC::Sender* sender = content::RenderThread::Get();
2387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(sender);
2397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!sender->Send(new NaClHostMsg_NaClCreateTemporaryFile(
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &transit_fd))) {
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return base::kInvalidPlatformFileValue;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (transit_fd == IPC::InvalidPlatformFileForTransit()) {
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return base::kInvalidPlatformFileValue;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::PlatformFile handle = IPC::PlatformFileForTransitToPlatformFile(
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      transit_fd);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return handle;
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
253eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint32_t GetNexeFd(PP_Instance instance,
2547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                  const char* pexe_url,
2557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                  uint32_t abi_version,
2567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                  uint32_t opt_level,
2577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                  const char* last_modified,
2587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                  const char* etag,
259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                  PP_Bool* is_hit,
260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                  PP_FileHandle* handle,
261eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                  struct PP_CompletionCallback callback) {
262eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ppapi::thunk::EnterInstance enter(instance, callback);
263eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (enter.failed())
264eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return enter.retval();
2657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!pexe_url || !last_modified || !etag || !is_hit || !handle)
2667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return enter.SetResult(PP_ERROR_BADARGUMENT);
2677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!InitializePnaclResourceHost())
2687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return enter.SetResult(PP_ERROR_FAILED);
2697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::Time last_modified_time;
2717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // If FromString fails, it doesn't touch last_modified_time and we just send
2727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // the default-constructed null value.
2737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::Time::FromString(last_modified, &last_modified_time);
2747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  nacl::PnaclCacheInfo cache_info;
2767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  cache_info.pexe_url = GURL(pexe_url);
2777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  cache_info.abi_version = abi_version;
2787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  cache_info.opt_level = opt_level;
2797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  cache_info.last_modified = last_modified_time;
2807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  cache_info.etag = std::string(etag);
2817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  g_pnacl_resource_host.Get()->RequestNexeFd(
2837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      GetRoutingID(instance),
284ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      instance,
2857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      cache_info,
2867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      is_hit,
2877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      handle,
2887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      enter.callback());
2897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return enter.SetResult(PP_OK_COMPLETIONPENDING);
291eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
292eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
293bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochvoid ReportTranslationFinished(PP_Instance instance, PP_Bool success) {
2947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // If the resource host isn't initialized, don't try to do that here.
2957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Just return because something is already very wrong.
2967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (g_pnacl_resource_host.Get() == NULL)
2977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
298bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  g_pnacl_resource_host.Get()->ReportTranslationFinished(instance, success);
299eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
300eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Bool IsOffTheRecord() {
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_FromBool(ChromeRenderProcessObserver::is_incognito_process());
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Bool IsPnaclEnabled() {
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return PP_FromBool(
307f968bfd8e7e7331d11d96f3ef27f3d9212e92c39Ben Murdoch      CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnablePnacl));
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
310a3f7b4e666c476898878fa745f637129375cd889Ben MurdochPP_ExternalPluginResult ReportNaClError(PP_Instance instance,
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              PP_NaClError error_id) {
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  IPC::Sender* sender = content::RenderThread::Get();
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!sender->Send(
3157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          new NaClHostMsg_NaClErrorStatus(
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              // TODO(dschuff): does this enum need to be sent as an int,
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              // or is it safe to include the appropriate headers in
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              // render_messages.h?
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              GetRoutingID(instance), static_cast<int>(error_id)))) {
320a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    return PP_EXTERNAL_PLUGIN_FAILED;
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
322a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  return PP_EXTERNAL_PLUGIN_OK;
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)PP_FileHandle OpenNaClExecutable(PP_Instance instance,
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 const char* file_url,
32790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                 uint64_t* nonce_lo,
32890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                 uint64_t* nonce_hi) {
329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IPC::PlatformFileForTransit out_fd = IPC::InvalidPlatformFileForTransit();
330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IPC::Sender* sender = content::RenderThread::Get();
3317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(sender);
33290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  *nonce_lo = 0;
33390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  *nonce_hi = 0;
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::FilePath file_path;
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!sender->Send(
3367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      new NaClHostMsg_OpenNaClExecutable(GetRoutingID(instance),
337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                               GURL(file_url),
33890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                               &out_fd,
33990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                               nonce_lo,
34090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                               nonce_hi))) {
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return base::kInvalidPlatformFileValue;
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (out_fd == IPC::InvalidPlatformFileForTransit()) {
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return base::kInvalidPlatformFileValue;
346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::PlatformFile handle =
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      IPC::PlatformFileForTransitToPlatformFile(out_fd);
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return handle;
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const PPB_NaCl_Private nacl_interface = {
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  &LaunchSelLdr,
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  &StartPpapiProxy,
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  &UrandomFD,
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  &Are3DInterfacesDisabled,
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  &BrokerDuplicateHandle,
3592385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  &EnsurePnaclInstalled,
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  &GetReadonlyPnaclFD,
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  &CreateTemporaryFile,
362eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  &GetNexeFd,
363eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  &ReportTranslationFinished,
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  &IsOffTheRecord,
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  &IsPnaclEnabled,
366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  &ReportNaClError,
367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  &OpenNaClExecutable
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const PPB_NaCl_Private* PPB_NaCl_Private_Impl::GetInterface() {
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return &nacl_interface;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // DISABLE_NACL
377