blob: c7cf91b7e6f712ef9887bf13c01665ce42566268 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ppapi/native_client/src/trusted/plugin/pnacl_resources.h"
#include "native_client/src/include/portability_io.h"
#include "native_client/src/shared/platform/nacl_check.h"
#include "native_client/src/trusted/desc/nacl_desc_wrapper.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/native_client/src/trusted/plugin/plugin.h"
#include "ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h"
#include "ppapi/native_client/src/trusted/plugin/utility.h"
namespace plugin {
namespace {
static const char kPnaclBaseUrl[] = "chrome://pnacl-translator/";
nacl::string GetFullUrl(const nacl::string& partial_url) {
return nacl::string(kPnaclBaseUrl) + GetNaClInterface()->GetSandboxArch() +
"/" + partial_url;
}
} // namespace
// Determine if a URL is for a pnacl-component file, or if it is some other
// type of URL (e.g., http://, https://, chrome-extension://).
// The URL could be one of the other variants for shared libraries
// served from the web.
bool PnaclUrls::IsPnaclComponent(const nacl::string& full_url) {
return full_url.find(kPnaclBaseUrl, 0) == 0;
}
// Convert a URL to a filename accepted by GetReadonlyPnaclFd.
// Must be kept in sync with chrome/browser/nacl_host/nacl_file_host.
nacl::string PnaclUrls::PnaclComponentURLToFilename(
const nacl::string& full_url) {
// strip component scheme.
nacl::string r = full_url.substr(nacl::string(kPnaclBaseUrl).length());
// Use white-listed-chars.
size_t replace_pos;
static const char* white_list = "abcdefghijklmnopqrstuvwxyz0123456789_";
replace_pos = r.find_first_not_of(white_list);
while(replace_pos != nacl::string::npos) {
r = r.replace(replace_pos, 1, "_");
replace_pos = r.find_first_not_of(white_list);
}
return r;
}
//////////////////////////////////////////////////////////////////////
PnaclResources::~PnaclResources() {
if (llc_file_handle_ != PP_kInvalidFileHandle)
CloseFileHandle(llc_file_handle_);
if (ld_file_handle_ != PP_kInvalidFileHandle)
CloseFileHandle(ld_file_handle_);
}
void PnaclResources::ReadResourceInfo(
const pp::CompletionCallback& resource_info_read_cb) {
nacl::string full_url = "chrome://pnacl-translator/pnacl.json";
nacl::string resource_info_filename =
PnaclUrls::PnaclComponentURLToFilename(full_url);
PLUGIN_PRINTF(("Pnacl-converted resources info url: %s\n",
resource_info_filename.c_str()));
PP_Var pp_llc_tool_name_var;
PP_Var pp_ld_tool_name_var;
if (!plugin_->nacl_interface()->GetPnaclResourceInfo(
plugin_->pp_instance(),
resource_info_filename.c_str(),
&pp_llc_tool_name_var,
&pp_ld_tool_name_var)) {
coordinator_->ExitWithError();
}
pp::Var llc_tool_name(pp::PASS_REF, pp_llc_tool_name_var);
pp::Var ld_tool_name(pp::PASS_REF, pp_ld_tool_name_var);
llc_tool_name_ = GetFullUrl(llc_tool_name.AsString());
ld_tool_name_ = GetFullUrl(ld_tool_name.AsString());
pp::Module::Get()->core()->CallOnMainThread(0, resource_info_read_cb, PP_OK);
}
PP_FileHandle PnaclResources::TakeLlcFileHandle() {
PP_FileHandle to_return = llc_file_handle_;
llc_file_handle_ = PP_kInvalidFileHandle;
return to_return;
}
PP_FileHandle PnaclResources::TakeLdFileHandle() {
PP_FileHandle to_return = ld_file_handle_;
ld_file_handle_ = PP_kInvalidFileHandle;
return to_return;
}
void PnaclResources::StartLoad(
const pp::CompletionCallback& all_loaded_callback) {
PLUGIN_PRINTF(("PnaclResources::StartLoad\n"));
// Do a blocking load of each of the resources.
nacl::string llc_filename =
PnaclUrls::PnaclComponentURLToFilename(llc_tool_name_);
llc_file_handle_ =
plugin_->nacl_interface()->GetReadonlyPnaclFd(llc_filename.c_str());
nacl::string ld_filename =
PnaclUrls::PnaclComponentURLToFilename(ld_tool_name_);
ld_file_handle_ =
plugin_->nacl_interface()->GetReadonlyPnaclFd(ld_filename.c_str());
int32_t result = PP_OK;
if (llc_file_handle_ == PP_kInvalidFileHandle ||
ld_file_handle_ == PP_kInvalidFileHandle) {
// File-open failed. Assume this means that the file is
// not actually installed. This shouldn't actually occur since
// ReadResourceInfo() fail first.
coordinator_->ReportNonPpapiError(
PP_NACL_ERROR_PNACL_RESOURCE_FETCH,
nacl::string("The Portable Native Client (pnacl) component is not "
"installed. Please consult chrome://components for more "
"information."));
result = PP_ERROR_FILENOTFOUND;
}
pp::Module::Get()->core()->CallOnMainThread(0, all_loaded_callback, result);
}
} // namespace plugin