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.
6 // The portable representation of an instance and root scriptable object.
7 // The PPAPI version of the plugin instantiates a subclass of this class.
9 #ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PLUGIN_H_
10 #define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PLUGIN_H_
19 #include "native_client/src/include/nacl_macros.h"
20 #include "native_client/src/include/nacl_scoped_ptr.h"
21 #include "native_client/src/include/nacl_string.h"
22 #include "native_client/src/public/nacl_file_info.h"
24 #include "ppapi/c/private/ppb_nacl_private.h"
25 #include "ppapi/cpp/instance.h"
26 #include "ppapi/cpp/private/uma_private.h"
27 #include "ppapi/cpp/url_loader.h"
28 #include "ppapi/cpp/var.h"
29 #include "ppapi/cpp/view.h"
31 #include "ppapi/native_client/src/trusted/plugin/nacl_subprocess.h"
32 #include "ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h"
33 #include "ppapi/native_client/src/trusted/plugin/service_runtime.h"
34 #include "ppapi/native_client/src/trusted/plugin/utility.h"
36 #include "ppapi/utility/completion_callback_factory.h"
40 class DescWrapperFactory
;
44 class CompletionCallback
;
54 int32_t ConvertFileDescriptor(PP_FileHandle handle
);
56 const PP_NaClFileInfo kInvalidNaClFileInfo
= {
57 PP_kInvalidFileHandle
,
62 class Plugin
: public pp::Instance
{
64 explicit Plugin(PP_Instance instance
);
66 // ----- Methods inherited from pp::Instance:
68 // Initializes this plugin with <embed/object ...> tag attribute count |argc|,
69 // names |argn| and values |argn|. Returns false on failure.
70 // Gets called by the browser right after New().
71 virtual bool Init(uint32_t argc
, const char* argn
[], const char* argv
[]);
73 // Handles document load, when the plugin is a MIME type handler.
74 virtual bool HandleDocumentLoad(const pp::URLLoader
& url_loader
);
78 // Starts NaCl module but does not wait until low-level
79 // initialization (e.g. ld.so dynamic loading of manifest files) is
80 // done. The module will become ready later, asynchronously. Other
81 // event handlers should block until the module is ready before
82 // trying to communicate with it, i.e., until nacl_ready_state is
85 // NB: currently we do not time out, so if the untrusted code
86 // does not signal that it is ready, then we will deadlock the main
87 // thread of the renderer on this subsequent event delivery. We
88 // should include a time-out at which point we declare the
89 // nacl_ready_state to be done, and let the normal crash detection
90 // mechanism(s) take over.
91 void LoadNaClModule(PP_NaClFileInfo file_info
,
92 bool uses_nonsfi_mode
,
93 bool enable_dyncode_syscalls
,
94 bool enable_exception_handling
,
95 bool enable_crash_throttling
,
96 const pp::CompletionCallback
& init_done_cb
,
97 const pp::CompletionCallback
& crash_cb
);
99 // Finish hooking interfaces up, after low-level initialization is
101 bool LoadNaClModuleContinuationIntern();
103 // Continuation for starting SRPC/JSProxy services as appropriate.
104 // This is invoked as a callback when the NaCl module makes the
105 // init_done reverse RPC to tell us that low-level initialization
106 // such as ld.so processing is done. That initialization requires
107 // that the main thread be free in order to do Pepper
108 // main-thread-only operations such as file processing.
109 bool LoadNaClModuleContinuation(int32_t pp_error
);
112 // A helper SRPC NaCl module can be loaded given a PP_NaClFileInfo.
113 // Blocks until the helper module signals initialization is done.
114 // Does not update nacl_module_origin().
115 // Returns NULL or the NaClSubprocess of the new helper NaCl module.
116 NaClSubprocess
* LoadHelperNaClModule(const nacl::string
& helper_url
,
117 PP_NaClFileInfo file_info
,
118 ErrorInfo
* error_info
);
120 // Report an error that was encountered while loading a module.
121 void ReportLoadError(const ErrorInfo
& error_info
);
123 nacl::DescWrapperFactory
* wrapper_factory() const { return wrapper_factory_
; }
125 // A helper function that indicates if |url| can be requested by the document
126 // under the same-origin policy. Strictly speaking, it may be possible for the
127 // document to request the URL using CORS even if this function returns false.
128 bool DocumentCanRequest(const std::string
& url
);
130 const PPB_NaCl_Private
* nacl_interface() const { return nacl_interface_
; }
131 pp::UMAPrivate
& uma_interface() { return uma_interface_
; }
134 NACL_DISALLOW_COPY_AND_ASSIGN(Plugin
);
135 // The browser will invoke the destructor via the pp::Instance
136 // pointer to this object, not from base's Delete().
139 // Shuts down socket connection, service runtime, and receive thread,
140 // in this order, for the main nacl subprocess.
141 void ShutDownSubprocesses();
143 // Histogram helper functions, internal to Plugin so they can use
144 // uma_interface_ normally.
145 void HistogramTimeSmall(const std::string
& name
, int64_t ms
);
147 // Loads and starts a helper (e.g. llc, ld) NaCl module.
148 // Only to be used from a background (non-main) thread for the PNaCl
149 // translator. This will fully initialize the |subprocess| if the load was
151 bool LoadHelperNaClModuleInternal(NaClSubprocess
* subprocess
,
152 const SelLdrStartParams
& params
);
154 // Start sel_ldr from the main thread, given the start params.
155 // |pp_error| is set by CallOnMainThread (should be PP_OK).
156 void StartSelLdrOnMainThread(int32_t pp_error
,
157 ServiceRuntime
* service_runtime
,
158 const SelLdrStartParams
& params
,
159 pp::CompletionCallback callback
);
161 // Signals that StartSelLdr has finished.
162 // This is invoked on the main thread.
163 void SignalStartSelLdrDone(int32_t pp_error
,
165 ServiceRuntime
* service_runtime
);
167 // This is invoked on the main thread.
168 void StartNexe(int32_t pp_error
, ServiceRuntime
* service_runtime
);
170 // Callback used when getting the URL for the .nexe file. If the URL loading
171 // is successful, the file descriptor is opened and can be passed to sel_ldr
172 // with the sandbox on.
173 void NexeFileDidOpen(int32_t pp_error
);
174 void NexeFileDidOpenContinuation(int32_t pp_error
);
176 // Callback used when the reverse channel closes. This is an
177 // asynchronous event that might turn into a JavaScript error or
178 // crash event -- this is controlled by the two state variables
179 // nacl_ready_state_ and nexe_error_reported_: If an error or crash
180 // had already been reported, no additional crash event is
181 // generated. If no error has been reported but nacl_ready_state_
182 // is not DONE, then the loadend event has not been reported, and we
183 // enqueue an error event followed by loadend. If nacl_ready_state_
184 // is DONE, then we are in the post-loadend (we need temporal
185 // predicate symbols), and we enqueue a crash event.
186 void NexeDidCrash(int32_t pp_error
);
188 // Callback used when a .nexe is translated from bitcode. If the translation
189 // is successful, the file descriptor is opened and can be passed to sel_ldr
190 // with the sandbox on.
191 void BitcodeDidTranslate(int32_t pp_error
);
192 void BitcodeDidTranslateContinuation(int32_t pp_error
);
194 // NaCl ISA selection manifest file support. The manifest file is specified
195 // using the "nacl" attribute in the <embed> tag. First, the manifest URL (or
196 // data: URI) is fetched, then the JSON is parsed. Once a valid .nexe is
197 // chosen for the sandbox ISA, any current service runtime is shut down, the
198 // .nexe is loaded and run.
200 // Callback used when getting the manifest file as a local file descriptor.
201 void NaClManifestFileDidOpen(int32_t pp_error
);
203 // Processes the JSON manifest string and starts loading the nexe.
204 void ProcessNaClManifest(const nacl::string
& manifest_json
);
206 // Keep track of the NaCl module subprocess that was spun up in the plugin.
207 NaClSubprocess main_subprocess_
;
209 bool uses_nonsfi_mode_
;
211 nacl::DescWrapperFactory
* wrapper_factory_
;
213 pp::CompletionCallbackFactory
<Plugin
> callback_factory_
;
215 nacl::scoped_ptr
<PnaclCoordinator
> pnacl_coordinator_
;
219 PP_NaClFileInfo nexe_file_info_
;
221 const PPB_NaCl_Private
* nacl_interface_
;
222 pp::UMAPrivate uma_interface_
;
225 } // namespace plugin
227 #endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PLUGIN_H_