Home | History | Annotate | Download | only in plugin
      1 // -*- c++ -*-
      2 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 
      6 // The portable representation of an instance and root scriptable object.
      7 // The PPAPI version of the plugin instantiates a subclass of this class.
      8 
      9 #ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PLUGIN_H_
     10 #define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PLUGIN_H_
     11 
     12 #include <stdio.h>
     13 
     14 #include <string>
     15 
     16 #include "native_client/src/include/nacl_macros.h"
     17 #include "native_client/src/include/nacl_scoped_ptr.h"
     18 
     19 #include "ppapi/c/private/ppb_nacl_private.h"
     20 #include "ppapi/cpp/instance.h"
     21 #include "ppapi/cpp/private/uma_private.h"
     22 #include "ppapi/cpp/url_loader.h"
     23 #include "ppapi/cpp/var.h"
     24 #include "ppapi/cpp/view.h"
     25 
     26 #include "ppapi/native_client/src/trusted/plugin/nacl_subprocess.h"
     27 #include "ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h"
     28 #include "ppapi/native_client/src/trusted/plugin/service_runtime.h"
     29 #include "ppapi/native_client/src/trusted/plugin/utility.h"
     30 
     31 #include "ppapi/utility/completion_callback_factory.h"
     32 
     33 namespace nacl {
     34 class DescWrapper;
     35 class DescWrapperFactory;
     36 }  // namespace nacl
     37 
     38 namespace pp {
     39 class CompletionCallback;
     40 class URLLoader;
     41 class URLUtil_Dev;
     42 }
     43 
     44 namespace plugin {
     45 
     46 class ErrorInfo;
     47 class Manifest;
     48 
     49 int32_t ConvertFileDescriptor(PP_FileHandle handle);
     50 
     51 const PP_NaClFileInfo kInvalidNaClFileInfo = {
     52   PP_kInvalidFileHandle,
     53   0,  // token_lo
     54   0,  // token_hi
     55 };
     56 
     57 class Plugin : public pp::Instance {
     58  public:
     59   explicit Plugin(PP_Instance instance);
     60 
     61   // ----- Methods inherited from pp::Instance:
     62 
     63   // Initializes this plugin with <embed/object ...> tag attribute count |argc|,
     64   // names |argn| and values |argn|. Returns false on failure.
     65   // Gets called by the browser right after New().
     66   virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]);
     67 
     68   // Handles document load, when the plugin is a MIME type handler.
     69   virtual bool HandleDocumentLoad(const pp::URLLoader& url_loader);
     70 
     71   // Load support.
     72   //
     73   // Starts NaCl module but does not wait until low-level
     74   // initialization (e.g. ld.so dynamic loading of manifest files) is
     75   // done.  The module will become ready later, asynchronously.  Other
     76   // event handlers should block until the module is ready before
     77   // trying to communicate with it, i.e., until nacl_ready_state is
     78   // DONE.
     79   //
     80   // NB: currently we do not time out, so if the untrusted code
     81   // does not signal that it is ready, then we will deadlock the main
     82   // thread of the renderer on this subsequent event delivery.  We
     83   // should include a time-out at which point we declare the
     84   // nacl_ready_state to be done, and let the normal crash detection
     85   // mechanism(s) take over.
     86   void LoadNaClModule(PP_NaClFileInfo file_info,
     87                       bool uses_nonsfi_mode,
     88                       bool enable_dyncode_syscalls,
     89                       bool enable_exception_handling,
     90                       bool enable_crash_throttling,
     91                       const pp::CompletionCallback& init_done_cb);
     92 
     93   // Finish hooking interfaces up, after low-level initialization is
     94   // complete.
     95   bool LoadNaClModuleContinuationIntern();
     96 
     97   // Continuation for starting SRPC/JSProxy services as appropriate.
     98   // This is invoked as a callback when the NaCl module makes the
     99   // init_done reverse RPC to tell us that low-level initialization
    100   // such as ld.so processing is done.  That initialization requires
    101   // that the main thread be free in order to do Pepper
    102   // main-thread-only operations such as file processing.
    103   bool LoadNaClModuleContinuation(int32_t pp_error);
    104 
    105   // Load support.
    106   // A helper SRPC NaCl module can be loaded given a PP_NaClFileInfo.
    107   // Blocks until the helper module signals initialization is done.
    108   // Does not update nacl_module_origin().
    109   // Returns NULL or the NaClSubprocess of the new helper NaCl module.
    110   NaClSubprocess* LoadHelperNaClModule(const std::string& helper_url,
    111                                        PP_NaClFileInfo file_info,
    112                                        ErrorInfo* error_info);
    113 
    114   // Report an error that was encountered while loading a module.
    115   void ReportLoadError(const ErrorInfo& error_info);
    116 
    117   nacl::DescWrapperFactory* wrapper_factory() const { return wrapper_factory_; }
    118 
    119   const PPB_NaCl_Private* nacl_interface() const { return nacl_interface_; }
    120   pp::UMAPrivate& uma_interface() { return uma_interface_; }
    121 
    122  private:
    123   NACL_DISALLOW_COPY_AND_ASSIGN(Plugin);
    124   // The browser will invoke the destructor via the pp::Instance
    125   // pointer to this object, not from base's Delete().
    126   ~Plugin();
    127 
    128   // Shuts down socket connection, service runtime, and receive thread,
    129   // in this order, for the main nacl subprocess.
    130   void ShutDownSubprocesses();
    131 
    132   // Histogram helper functions, internal to Plugin so they can use
    133   // uma_interface_ normally.
    134   void HistogramTimeSmall(const std::string& name, int64_t ms);
    135 
    136   // Loads and starts a helper (e.g. llc, ld) NaCl module.
    137   // Only to be used from a background (non-main) thread for the PNaCl
    138   // translator. This will fully initialize the |subprocess| if the load was
    139   // successful.
    140   bool LoadHelperNaClModuleInternal(NaClSubprocess* subprocess,
    141                                     const SelLdrStartParams& params);
    142 
    143   // Start sel_ldr from the main thread, given the start params.
    144   // |pp_error| is set by CallOnMainThread (should be PP_OK).
    145   void StartSelLdrOnMainThread(int32_t pp_error,
    146                                ServiceRuntime* service_runtime,
    147                                const SelLdrStartParams& params,
    148                                pp::CompletionCallback callback);
    149 
    150   // Signals that StartSelLdr has finished.
    151   // This is invoked on the main thread.
    152   void SignalStartSelLdrDone(int32_t pp_error,
    153                              bool* started,
    154                              ServiceRuntime* service_runtime);
    155 
    156   // This is invoked on the main thread.
    157   void StartNexe(int32_t pp_error, ServiceRuntime* service_runtime);
    158 
    159   // Callback used when getting the URL for the .nexe file.  If the URL loading
    160   // is successful, the file descriptor is opened and can be passed to sel_ldr
    161   // with the sandbox on.
    162   void NexeFileDidOpen(int32_t pp_error);
    163   void NexeFileDidOpenContinuation(int32_t pp_error);
    164 
    165   // Callback used when a .nexe is translated from bitcode.  If the translation
    166   // is successful, the file descriptor is opened and can be passed to sel_ldr
    167   // with the sandbox on.
    168   void BitcodeDidTranslate(int32_t pp_error);
    169   void BitcodeDidTranslateContinuation(int32_t pp_error);
    170 
    171   // NaCl ISA selection manifest file support.  The manifest file is specified
    172   // using the "nacl" attribute in the <embed> tag.  First, the manifest URL (or
    173   // data: URI) is fetched, then the JSON is parsed.  Once a valid .nexe is
    174   // chosen for the sandbox ISA, any current service runtime is shut down, the
    175   // .nexe is loaded and run.
    176 
    177   // Callback used when getting the manifest file as a local file descriptor.
    178   void NaClManifestFileDidOpen(int32_t pp_error);
    179 
    180   // Processes the JSON manifest string and starts loading the nexe.
    181   void ProcessNaClManifest(const std::string& manifest_json);
    182 
    183   // Keep track of the NaCl module subprocess that was spun up in the plugin.
    184   NaClSubprocess main_subprocess_;
    185 
    186   bool uses_nonsfi_mode_;
    187 
    188   nacl::DescWrapperFactory* wrapper_factory_;
    189 
    190   pp::CompletionCallbackFactory<Plugin> callback_factory_;
    191 
    192   nacl::scoped_ptr<PnaclCoordinator> pnacl_coordinator_;
    193 
    194   int exit_status_;
    195 
    196   PP_NaClFileInfo nexe_file_info_;
    197 
    198   const PPB_NaCl_Private* nacl_interface_;
    199   pp::UMAPrivate uma_interface_;
    200 };
    201 
    202 }  // namespace plugin
    203 
    204 #endif  // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PLUGIN_H_
    205