Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(132)

Side by Side Diff: src/trusted/plugin/plugin.h

Issue 7799028: Remove src/trusted/plugin (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: fix gyp file for necessary -I Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/trusted/plugin/osx_ppapi/ppNaClPlugin.r ('k') | src/trusted/plugin/plugin.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2011 The Native Client 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
7 // The portable representation of an instance and root scriptable object.
8 // The PPAPI version of the plugin instantiates a subclass of this class.
9
10 #ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PLUGIN_H_
11 #define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PLUGIN_H_
12
13 #include <stdio.h>
14 #include <map>
15 #include <set>
16 #include <queue>
17 #include <string>
18 #include <vector>
19
20 #include "native_client/src/include/nacl_macros.h"
21 #include "native_client/src/include/nacl_scoped_ptr.h"
22 #include "native_client/src/include/nacl_string.h"
23 #include "native_client/src/trusted/plugin/file_downloader.h"
24 #include "native_client/src/trusted/plugin/method_map.h"
25 #include "native_client/src/trusted/plugin/nacl_subprocess.h"
26 #include "native_client/src/trusted/plugin/pnacl_coordinator.h"
27 #include "native_client/src/trusted/plugin/service_runtime.h"
28 #include "native_client/src/trusted/plugin/utility.h"
29
30 #include "ppapi/cpp/private/var_private.h"
31 // for pp::VarPrivate
32 #include "ppapi/cpp/private/instance_private.h"
33 #include "ppapi/cpp/rect.h"
34 #include "ppapi/cpp/url_loader.h"
35 #include "ppapi/cpp/var.h"
36
37 struct NaClSrpcChannel;
38 struct NaClDesc;
39
40 namespace nacl {
41 class DescWrapper;
42 class DescWrapperFactory;
43 } // namespace nacl
44
45 namespace pp {
46 class Find_Dev;
47 class Printing_Dev;
48 class Selection_Dev;
49 class URLLoader;
50 class WidgetClient_Dev;
51 class URLUtil_Dev;
52 class Zoom_Dev;
53 }
54
55 namespace ppapi_proxy {
56 class BrowserPpp;
57 }
58
59 namespace plugin {
60
61 class ErrorInfo;
62 class Manifest;
63 class PnaclCoordinator;
64 class ProgressEvent;
65 class ScriptableHandle;
66
67 typedef enum {
68 METHOD_CALL = 0,
69 PROPERTY_GET,
70 PROPERTY_SET
71 } CallType;
72
73
74 class Plugin : public pp::InstancePrivate {
75 public:
76 // Factory method for creation.
77 static Plugin* New(PP_Instance instance);
78
79 // ----- Methods inherited from pp::Instance:
80
81 // Initializes this plugin with <embed/object ...> tag attribute count |argc|,
82 // names |argn| and values |argn|. Returns false on failure.
83 // Gets called by the browser right after New().
84 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]);
85
86 // Handles view changes from the browser.
87 virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip);
88
89 // Handles gaining or losing focus.
90 virtual void DidChangeFocus(bool has_focus);
91
92 // Handles input events delivered from the browser to this plugin element.
93 virtual bool HandleInputEvent(const pp::InputEvent& event);
94
95 // Handles gaining or losing focus.
96 virtual bool HandleDocumentLoad(const pp::URLLoader& url_loader);
97
98 // Returns a scriptable reference to this plugin element.
99 // Called by JavaScript document.getElementById(plugin_id).
100 virtual pp::Var GetInstanceObject();
101
102 // Handles postMessage from browser
103 virtual void HandleMessage(const pp::Var& message);
104
105 // ----- Plugin interface support.
106
107 // Load support.
108 // NaCl module can be loaded given a DescWrapper.
109 //
110 // Starts NaCl module but does not wait until low-level
111 // initialization (e.g., ld.so dynamic loading of manifest files) is
112 // done. The module will become ready later, asynchronously. Other
113 // event handlers should block until the module is ready before
114 // trying to communicate with it, i.e., until nacl_ready_state is
115 // DONE. Note, however, we already have another mechanism that
116 // prevents event delivery: StartJSObjectProxy plumbs through
117 // NaClSubprocess to SrpcClient which upcalls
118 // Plugin::StartProxiedExecution, which sets ppapi_proxy_. And NULL
119 // == ppapi_proxy_ prevents events from being delivered, even if
120 // nacl_ready_state is DONE.
121 //
122 // NB: currently we do not time out, so if the untrusted code
123 // does not signal that it is ready, then we will deadlock the main
124 // thread of the renderer on this subsequent event delivery. We
125 // should include a time-out at which point we declare the
126 // nacl_ready_state to be done, and let the normal crash detection
127 // mechanism(s) take over.
128 //
129 // Updates nacl_module_origin() and nacl_module_url().
130 bool LoadNaClModule(nacl::DescWrapper* wrapper, ErrorInfo* error_info,
131 pp::CompletionCallback init_done_cb);
132
133 // Finish hooking interfaces up, after low-level initialization is
134 // complete.
135 bool LoadNaClModuleContinuationIntern(ErrorInfo* error_info);
136
137 // Continuation for starting SRPC/JSProxy services as appropriate.
138 // This is invoked as a callback when the NaCl module makes the
139 // init_done reverse RPC to tell us that low-level initialization
140 // such as ld.so processing is done. That initialization requires
141 // that the main thread be free in order to do Pepper
142 // main-thread-only operations such as file processing.
143 bool LoadNaClModuleContinuation(int32_t pp_error);
144
145 // Load support.
146 // A helper SRPC NaCl module can be loaded given a DescWrapper.
147 // Blocks until the helper module signals initialization is done.
148 // Does not update nacl_module_origin().
149 // Returns kInvalidNaClSubprocessId or the ID of the new helper NaCl module.
150 NaClSubprocessId LoadHelperNaClModule(nacl::DescWrapper* wrapper,
151 ErrorInfo* error_info);
152
153 // Returns the argument value for the specified key, or NULL if not found.
154 // The callee retains ownership of the result.
155 char* LookupArgument(const char* key);
156
157 enum LengthComputable {
158 LENGTH_IS_NOT_COMPUTABLE = 0,
159 LENGTH_IS_COMPUTABLE = 1
160 };
161 // Report successful loading of a module.
162 void ReportLoadSuccess(LengthComputable length_computable,
163 uint64_t loaded_bytes,
164 uint64_t total_bytes);
165 // Report an error that was encountered while loading a module.
166 void ReportLoadError(const ErrorInfo& error_info);
167 // Report loading a module was aborted, typically due to user action.
168 void ReportLoadAbort();
169 // Dispatch a JavaScript event to indicate a key step in loading.
170 // |event_type| is a character string indicating which type of progress
171 // event (loadstart, progress, error, abort, load, loadend). Events are
172 // enqueued on the JavaScript event loop, which then calls back through
173 // DispatchProgressEvent.
174 void EnqueueProgressEvent(const char* event_type,
175 LengthComputable length_computable,
176 uint64_t loaded_bytes,
177 uint64_t total_bytes);
178
179 // Report the error code that sel_ldr produces when starting a nexe.
180 void ReportSelLdrLoadStatus(int status);
181
182 // Report nexe death after load to JS and shut down the proxy.
183 void ReportDeadNexe();
184
185 // The embed/object tag argument list.
186 int argc() const { return argc_; }
187 char** argn() const { return argn_; }
188 char** argv() const { return argv_; }
189
190 BrowserInterface* browser_interface() const { return browser_interface_; }
191 Plugin* plugin() const { return const_cast<Plugin*>(this); }
192
193 // URL resolution support.
194 // plugin_base_url is the URL used for resolving relative URLs used in
195 // src="...".
196 nacl::string plugin_base_url() const { return plugin_base_url_; }
197 void set_plugin_base_url(nacl::string url) { plugin_base_url_ = url; }
198 // manifest_base_url is the URL used for resolving relative URLs mentioned
199 // in manifest files. If the manifest is a data URI, this is an empty string.
200 nacl::string manifest_base_url() const { return manifest_base_url_; }
201 void set_manifest_base_url(nacl::string url) { manifest_base_url_ = url; }
202
203 // The URL of the manifest file as set by the "src" attribute.
204 // It is not the fully resolved URL if it was set as relative.
205 const nacl::string& manifest_url() const { return manifest_url_; }
206 void set_manifest_url(const nacl::string& manifest_url) {
207 manifest_url_ = manifest_url;
208 }
209
210 // The state of readiness of the plugin.
211 enum ReadyState {
212 // The trusted plugin begins in this ready state.
213 UNSENT = 0,
214 // The manifest file has been requested, but not yet received.
215 OPENED = 1,
216 // This state is unused.
217 HEADERS_RECEIVED = 2,
218 // The manifest file has been received and the nexe successfully requested.
219 LOADING = 3,
220 // The nexe has been loaded and the proxy started, so it is ready for
221 // interaction with the page.
222 DONE = 4
223 };
224 ReadyState nacl_ready_state() const { return nacl_ready_state_; }
225 void set_nacl_ready_state(ReadyState nacl_ready_state) {
226 nacl_ready_state_ = nacl_ready_state;
227 }
228
229 // Get the NaCl module subprocess that was assigned the ID |id|.
230 NaClSubprocess* nacl_subprocess(NaClSubprocessId id) const {
231 if (kInvalidNaClSubprocessId == id) {
232 return NULL;
233 }
234 return nacl_subprocesses_[id];
235 }
236 NaClSubprocessId next_nacl_subprocess_id() const {
237 return static_cast<NaClSubprocessId>(nacl_subprocesses_.size());
238 }
239
240 nacl::DescWrapperFactory* wrapper_factory() const { return wrapper_factory_; }
241
242 // Requests a NaCl manifest download from a |url| relative to the page origin.
243 void RequestNaClManifest(const nacl::string& url);
244
245 // Start up proxied execution of the browser API.
246 bool StartProxiedExecution(NaClSrpcChannel* srpc_channel,
247 ErrorInfo* error_info);
248
249 // Determines whether experimental APIs are usable.
250 static bool ExperimentalJavaScriptApisAreEnabled();
251
252 // Methods for method and property dispatch.
253 bool InitParams(uintptr_t method_id, CallType call_type, SrpcParams* params);
254 bool HasMethod(uintptr_t method_id, CallType call_type);
255 bool Invoke(uintptr_t method_id, CallType call_type, SrpcParams* params);
256 std::vector<uintptr_t>* GetPropertyIdentifiers() {
257 return property_get_methods_.Keys();
258 }
259
260 // The size returned when a file download operation is unable to determine
261 // the size of the file to load. W3C ProgressEvents specify that unknown
262 // sizes return 0.
263 static const uint64_t kUnknownBytes = 0;
264
265 // Getter for PPAPI proxy interface.
266 ppapi_proxy::BrowserPpp* ppapi_proxy() const { return ppapi_proxy_; }
267
268 // Called back by CallOnMainThread. Dispatches the first enqueued progress
269 // event.
270 void DispatchProgressEvent(int32_t result);
271
272 // Requests a URL asynchronously resulting in a call to pp_callback with
273 // a PP_Error indicating status. On success an open file descriptor
274 // corresponding to the url body is recorded for further lookup.
275 // This is used by SRPC-based StreamAsFile().
276 bool StreamAsFile(const nacl::string& url, PP_CompletionCallback pp_callback);
277 // Returns an open POSIX file descriptor retrieved by StreamAsFile()
278 // or NACL_NO_FILE_DESC. The caller must take ownership of the descriptor.
279 int32_t GetPOSIXFileDesc(const nacl::string& url);
280
281 // A helper function that gets the scheme type for |url|. Uses URLUtil_Dev
282 // interface which this class has as a member.
283 UrlSchemeType GetUrlScheme(const std::string& url);
284
285 // Get the text description of the last error reported by the plugin.
286 const nacl::string& last_error_string() const { return last_error_string_; }
287 void set_last_error_string(const nacl::string& error) {
288 last_error_string_ = error;
289 }
290
291 // The MIME type used to instantiate this instance of the NaCl plugin.
292 // Typically, the MIME type will be application/x-nacl. However, if the NEXE
293 // is being used as a content type handler for another content type (such as
294 // PDF), then this function will return that type.
295 const nacl::string& mime_type() const { return mime_type_; }
296 // The default MIME type for the NaCl plugin.
297 static const char* const kNaClMIMEType;
298 // Tests if the MIME type is not a NaCl MIME type.
299 bool IsForeignMIMEType() const;
300 // Returns true if PPAPI Dev interfaces should be allowed.
301 bool enable_dev_interface() { return enable_dev_interface_; }
302
303 Manifest const* manifest() const { return manifest_.get(); }
304
305 private:
306 NACL_DISALLOW_COPY_AND_ASSIGN(Plugin);
307 #ifndef HACK_FOR_MACOS_HANG_REMOVED
308 void XYZZY(const nacl::string& url, pp::VarPrivate js_callback);
309 #endif // HACK_FOR_MACOS_HANG_REMOVED
310 // Prevent construction and destruction from outside the class:
311 // must use factory New() method instead.
312 explicit Plugin(PP_Instance instance);
313 // The browser will invoke the destructor via the pp::Instance
314 // pointer to this object, not from base's Delete().
315 ~Plugin();
316
317 bool Init(BrowserInterface* browser_interface,
318 int argc,
319 char* argn[],
320 char* argv[]);
321 void LoadMethods();
322 // Shuts down socket connection, service runtime, and receive thread,
323 // in this order, for all spun up NaCl module subprocesses.
324 void ShutDownSubprocesses();
325
326 ScriptableHandle* scriptable_handle() const { return scriptable_handle_; }
327 void set_scriptable_handle(ScriptableHandle* scriptable_handle) {
328 scriptable_handle_ = scriptable_handle;
329 }
330
331 // Access the service runtime for the main NaCl subprocess.
332 ServiceRuntime* main_service_runtime() const {
333 return main_subprocess_.service_runtime();
334 }
335
336 // Setting the properties and methods exported.
337 void AddPropertyGet(RpcFunction function_ptr,
338 const char* name,
339 const char* outs);
340
341 // Help load a nacl module, from the file specified in wrapper.
342 // This will fully initialize the |subprocess| if the load was successful.
343 bool LoadNaClModuleCommon(nacl::DescWrapper* wrapper,
344 NaClSubprocess* subprocess,
345 ErrorInfo* error_info,
346 pp::CompletionCallback init_done_cb);
347 bool StartSrpcServices(NaClSubprocess* subprocess, ErrorInfo* error_info);
348 bool StartSrpcServicesCommon(NaClSubprocess* subprocess,
349 ErrorInfo* error_info);
350 bool StartJSObjectProxy(NaClSubprocess* subprocess, ErrorInfo* error_info);
351
352 MethodInfo* GetMethodInfo(uintptr_t method_id, CallType call_type);
353
354 // Check url and decide if PPAPI Dev interfaces are required.
355 bool RequiresDevInterface(const nacl::string& manifest_url);
356
357 // Callback used when getting the URL for the .nexe file. If the URL loading
358 // is successful, the file descriptor is opened and can be passed to sel_ldr
359 // with the sandbox on.
360 void NexeFileDidOpen(int32_t pp_error);
361 void NexeFileDidOpenContinuation(int32_t pp_error);
362
363 // Callback used when a .nexe is translated from bitcode. If the translation
364 // is successful, the file descriptor is opened and can be passed to sel_ldr
365 // with the sandbox on.
366 void BitcodeDidTranslate(int32_t pp_error);
367 void BitcodeDidTranslateContinuation(int32_t pp_error);
368
369 // NaCl ISA selection manifest file support. The manifest file is specified
370 // using the "nacl" attribute in the <embed> tag. First, the manifest URL (or
371 // data: URI) is fetched, then the JSON is parsed. Once a valid .nexe is
372 // chosen for the sandbox ISA, any current service runtime is shut down, the
373 // .nexe is loaded and run.
374
375 // Callback used when getting the manifest file as a buffer (e.g., data URIs)
376 void NaClManifestBufferReady(int32_t pp_error);
377
378 // Callback used when getting the manifest file as a local file descriptor.
379 void NaClManifestFileDidOpen(int32_t pp_error);
380
381 // Processes the JSON manifest string and starts loading the nexe.
382 void ProcessNaClManifest(const nacl::string& manifest_json);
383
384 // Parses the JSON in |manifest_json| and retains a Manifest in
385 // |manifest_| for use by subsequent resource lookups.
386 // On success, |true| is returned and |manifest_| is updated to
387 // contain a Manifest that is used by SelectNexeURLFromManifest.
388 // On failure, |false| is returned, and |manifest_| is unchanged.
389 bool SetManifestObject(const nacl::string& manifest_json,
390 ErrorInfo* error_info);
391
392 // Determines the URL of the program module appropriate for the NaCl sandbox
393 // implemented by the installed sel_ldr. The URL is determined from the
394 // Manifest in |manifest_|. On success, |true| is returned and |result| is
395 // set to the URL to use for the program, and |is_portable| is set to
396 // |true| if the program is portable bitcode.
397 // On failure, |false| is returned.
398 bool SelectProgramURLFromManifest(nacl::string* result,
399 ErrorInfo* error_info,
400 bool* is_portable);
401
402 // TODO(jvoung): get rid of these once we find a better way to store / install
403 // the pnacl translator nexes.
404 bool SelectLLCURLFromManifest(nacl::string* result,
405 ErrorInfo* error_info);
406 bool SelectLDURLFromManifest(nacl::string* result,
407 ErrorInfo* error_info);
408
409 // Logs timing information to a UMA histogram, and also logs the same timing
410 // information divided by the size of the nexe to another histogram.
411 void HistogramStartupTimeSmall(const std::string& name, float dt);
412 void HistogramStartupTimeMedium(const std::string& name, float dt);
413
414 // Determines the appropriate nexe for the sandbox and requests a load.
415 void RequestNexeLoad();
416
417 // Callback used when loading a URL for SRPC-based StreamAsFile().
418 void UrlDidOpenForStreamAsFile(int32_t pp_error,
419 FileDownloader*& url_downloader,
420 PP_CompletionCallback pp_callback);
421
422 // Shuts down the proxy for PPAPI nexes.
423 void ShutdownProxy(); // Nexe shutdown + proxy deletion.
424
425 BrowserInterface* browser_interface_;
426 ScriptableHandle* scriptable_handle_;
427
428 int argc_;
429 char** argn_;
430 char** argv_;
431
432 // Keep track of the NaCl module subprocesses that were spun up in the plugin.
433 NaClSubprocess main_subprocess_;
434 std::vector<NaClSubprocess*> nacl_subprocesses_;
435
436 nacl::string plugin_base_url_;
437 nacl::string manifest_base_url_;
438 nacl::string manifest_url_;
439 ReadyState nacl_ready_state_;
440
441 nacl::DescWrapperFactory* wrapper_factory_;
442
443 MethodMap property_get_methods_;
444
445 // File download support. |nexe_downloader_| can be opened with a specific
446 // callback to run when the file has been downloaded and is opened for
447 // reading. We use one downloader for all URL downloads to prevent issuing
448 // multiple GETs that might arrive out of order. For example, this will
449 // prevent a GET of a NaCl manifest while a .nexe GET is pending. Note that
450 // this will also prevent simultaneous handling of multiple .nexes on a page.
451 FileDownloader nexe_downloader_;
452 pp::CompletionCallbackFactory<Plugin> callback_factory_;
453
454 PnaclCoordinator pnacl_;
455
456 // The manifest dictionary. Used for looking up resources to be loaded.
457 nacl::scoped_ptr<Manifest> manifest_;
458 // URL processing interface for use in looking up resources in manifests.
459 const pp::URLUtil_Dev* url_util_;
460
461 // A string containing the text description of the last error produced by
462 // this plugin.
463 nacl::string last_error_string_;
464
465 // A pointer to the browser end of a proxy pattern connecting the
466 // NaCl plugin to the PPAPI .nexe's PPP interface
467 // (InitializeModule, Shutdown, and GetInterface).
468 // TODO(sehr): this should be a scoped_ptr for shutdown.
469 ppapi_proxy::BrowserPpp* ppapi_proxy_;
470
471 // PPAPI Dev interfaces are disabled by default.
472 bool enable_dev_interface_;
473
474 // If we get a DidChangeView event before the nexe is loaded, we store it and
475 // replay it to nexe after it's loaded.
476 bool replayDidChangeView;
477 pp::Rect replayDidChangeViewPosition;
478 pp::Rect replayDidChangeViewClip;
479
480 // If we get a HandleDocumentLoad event before the nexe is loaded, we store
481 // it and replay it to nexe after it's loaded.
482 bool replayHandleDocumentLoad;
483 pp::URLLoader replayHandleDocumentLoadURLLoader;
484
485 nacl::string mime_type_;
486
487 // Keep track of the FileDownloaders created to fetch urls.
488 std::set<FileDownloader*> url_downloaders_;
489 // Keep track of file descriptors opened by StreamAsFile().
490 // These are owned by the browser.
491 std::map<nacl::string, int32_t> url_fd_map_;
492
493 // Pending progress events.
494 std::queue<ProgressEvent*> progress_events_;
495
496 // Adapter class constructors require a reference to 'this', so we can't
497 // contain them directly.
498 nacl::scoped_ptr<pp::Find_Dev> find_adapter_;
499 nacl::scoped_ptr<pp::Printing_Dev> printing_adapter_;
500 nacl::scoped_ptr<pp::Selection_Dev> selection_adapter_;
501 nacl::scoped_ptr<pp::WidgetClient_Dev> widget_client_adapter_;
502 nacl::scoped_ptr<pp::Zoom_Dev> zoom_adapter_;
503
504 // used for NexeFileDidOpenContinuation
505 int64_t load_start_;
506
507 int64_t init_time_;
508 int64_t ready_time_;
509 size_t nexe_size_;
510 };
511
512 } // namespace plugin
513
514 #endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PLUGIN_H_
OLDNEW
« no previous file with comments | « src/trusted/plugin/osx_ppapi/ppNaClPlugin.r ('k') | src/trusted/plugin/plugin.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698