OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifdef _MSC_VER | 5 #ifdef _MSC_VER |
6 // Do not warn about use of std::copy with raw pointers. | 6 // Do not warn about use of std::copy with raw pointers. |
7 #pragma warning(disable : 4996) | 7 #pragma warning(disable : 4996) |
8 #endif | 8 #endif |
9 | 9 |
10 #include "native_client/src/trusted/plugin/plugin.h" | 10 #include "native_client/src/trusted/plugin/plugin.h" |
(...skipping 12 matching lines...) Expand all Loading... |
23 #include <vector> | 23 #include <vector> |
24 | 24 |
25 #include "native_client/src/include/nacl_base.h" | 25 #include "native_client/src/include/nacl_base.h" |
26 #include "native_client/src/include/nacl_macros.h" | 26 #include "native_client/src/include/nacl_macros.h" |
27 #include "native_client/src/include/nacl_scoped_ptr.h" | 27 #include "native_client/src/include/nacl_scoped_ptr.h" |
28 #include "native_client/src/include/nacl_string.h" | 28 #include "native_client/src/include/nacl_string.h" |
29 #include "native_client/src/include/portability.h" | 29 #include "native_client/src/include/portability.h" |
30 #include "native_client/src/include/portability_io.h" | 30 #include "native_client/src/include/portability_io.h" |
31 #include "native_client/src/include/portability_string.h" | 31 #include "native_client/src/include/portability_string.h" |
32 #include "native_client/src/shared/platform/nacl_check.h" | 32 #include "native_client/src/shared/platform/nacl_check.h" |
33 #include "native_client/src/shared/ppapi_proxy/browser_ppp.h" | |
34 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" | 33 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" |
35 #include "native_client/src/trusted/nonnacl_util/sel_ldr_launcher.h" | 34 #include "native_client/src/trusted/nonnacl_util/sel_ldr_launcher.h" |
36 #include "native_client/src/trusted/plugin/json_manifest.h" | 35 #include "native_client/src/trusted/plugin/json_manifest.h" |
37 #include "native_client/src/trusted/plugin/nacl_entry_points.h" | 36 #include "native_client/src/trusted/plugin/nacl_entry_points.h" |
38 #include "native_client/src/trusted/plugin/nacl_subprocess.h" | 37 #include "native_client/src/trusted/plugin/nacl_subprocess.h" |
39 #include "native_client/src/trusted/plugin/nexe_arch.h" | 38 #include "native_client/src/trusted/plugin/nexe_arch.h" |
40 #include "native_client/src/trusted/plugin/plugin_error.h" | 39 #include "native_client/src/trusted/plugin/plugin_error.h" |
41 #include "native_client/src/trusted/plugin/scriptable_plugin.h" | 40 #include "native_client/src/trusted/plugin/scriptable_plugin.h" |
42 #include "native_client/src/trusted/plugin/service_runtime.h" | 41 #include "native_client/src/trusted/plugin/service_runtime.h" |
43 #include "native_client/src/trusted/plugin/utility.h" | 42 #include "native_client/src/trusted/plugin/utility.h" |
(...skipping 16 matching lines...) Expand all Loading... |
60 #include "ppapi/cpp/dev/selection_dev.h" | 59 #include "ppapi/cpp/dev/selection_dev.h" |
61 #include "ppapi/cpp/dev/text_input_dev.h" | 60 #include "ppapi/cpp/dev/text_input_dev.h" |
62 #include "ppapi/cpp/dev/url_util_dev.h" | 61 #include "ppapi/cpp/dev/url_util_dev.h" |
63 #include "ppapi/cpp/dev/zoom_dev.h" | 62 #include "ppapi/cpp/dev/zoom_dev.h" |
64 #include "ppapi/cpp/image_data.h" | 63 #include "ppapi/cpp/image_data.h" |
65 #include "ppapi/cpp/input_event.h" | 64 #include "ppapi/cpp/input_event.h" |
66 #include "ppapi/cpp/module.h" | 65 #include "ppapi/cpp/module.h" |
67 #include "ppapi/cpp/mouse_lock.h" | 66 #include "ppapi/cpp/mouse_lock.h" |
68 #include "ppapi/cpp/rect.h" | 67 #include "ppapi/cpp/rect.h" |
69 | 68 |
70 using ppapi_proxy::BrowserPpp; | |
71 | |
72 namespace plugin { | 69 namespace plugin { |
73 | 70 |
74 namespace { | 71 namespace { |
75 | 72 |
76 const char* const kTypeAttribute = "type"; | 73 const char* const kTypeAttribute = "type"; |
77 // The "src" attribute of the <embed> tag. The value is expected to be either | 74 // The "src" attribute of the <embed> tag. The value is expected to be either |
78 // a URL or URI pointing to the manifest file (which is expected to contain | 75 // a URL or URI pointing to the manifest file (which is expected to contain |
79 // JSON matching ISAs with .nexe URLs). | 76 // JSON matching ISAs with .nexe URLs). |
80 const char* const kSrcManifestAttribute = "src"; | 77 const char* const kSrcManifestAttribute = "src"; |
81 // The "nacl" attribute of the <embed> tag. We use the value of this attribute | 78 // The "nacl" attribute of the <embed> tag. We use the value of this attribute |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 | 230 |
234 void HistogramEnumerateSelLdrLoadStatus(NaClErrorCode error_code) { | 231 void HistogramEnumerateSelLdrLoadStatus(NaClErrorCode error_code) { |
235 HistogramEnumerate("NaCl.LoadStatus.SelLdr", error_code, NACL_ERROR_CODE_MAX, | 232 HistogramEnumerate("NaCl.LoadStatus.SelLdr", error_code, NACL_ERROR_CODE_MAX, |
236 LOAD_STATUS_UNKNOWN); | 233 LOAD_STATUS_UNKNOWN); |
237 } | 234 } |
238 | 235 |
239 void HistogramEnumerateManifestIsDataURI(bool is_data_uri) { | 236 void HistogramEnumerateManifestIsDataURI(bool is_data_uri) { |
240 HistogramEnumerate("NaCl.Manifest.IsDataURI", is_data_uri, 2, -1); | 237 HistogramEnumerate("NaCl.Manifest.IsDataURI", is_data_uri, 2, -1); |
241 } | 238 } |
242 | 239 |
243 // Derive a class from pp::Find_Dev to forward PPP_Find_Dev calls to | |
244 // the plugin. | |
245 class FindAdapter : public pp::Find_Dev { | |
246 public: | |
247 explicit FindAdapter(Plugin* plugin) | |
248 : pp::Find_Dev(plugin), | |
249 plugin_(plugin) { | |
250 BrowserPpp* proxy = plugin_->ppapi_proxy(); | |
251 CHECK(proxy != NULL); | |
252 ppp_find_ = static_cast<const PPP_Find_Dev*>( | |
253 proxy->GetPluginInterface(PPP_FIND_DEV_INTERFACE)); | |
254 } | |
255 | |
256 bool StartFind(const std::string& text, bool case_sensitive) { | |
257 if (ppp_find_ != NULL) { | |
258 PP_Bool pp_success = | |
259 ppp_find_->StartFind(plugin_->pp_instance(), | |
260 text.c_str(), | |
261 PP_FromBool(case_sensitive)); | |
262 return pp_success == PP_TRUE; | |
263 } | |
264 return false; | |
265 } | |
266 | |
267 void SelectFindResult(bool forward) { | |
268 if (ppp_find_ != NULL) { | |
269 ppp_find_->SelectFindResult(plugin_->pp_instance(), | |
270 PP_FromBool(forward)); | |
271 } | |
272 } | |
273 | |
274 void StopFind() { | |
275 if (ppp_find_ != NULL) | |
276 ppp_find_->StopFind(plugin_->pp_instance()); | |
277 } | |
278 | |
279 private: | |
280 Plugin* plugin_; | |
281 const PPP_Find_Dev* ppp_find_; | |
282 | |
283 NACL_DISALLOW_COPY_AND_ASSIGN(FindAdapter); | |
284 }; | |
285 | |
286 | |
287 // Derive a class from pp::MouseLock to forward PPP_MouseLock calls to | |
288 // the plugin. | |
289 class MouseLockAdapter : public pp::MouseLock { | |
290 public: | |
291 explicit MouseLockAdapter(Plugin* plugin) | |
292 : pp::MouseLock(plugin), | |
293 plugin_(plugin) { | |
294 BrowserPpp* proxy = plugin_->ppapi_proxy(); | |
295 CHECK(proxy != NULL); | |
296 ppp_mouse_lock_ = static_cast<const PPP_MouseLock*>( | |
297 proxy->GetPluginInterface(PPP_MOUSELOCK_INTERFACE)); | |
298 } | |
299 | |
300 void MouseLockLost() { | |
301 if (ppp_mouse_lock_ != NULL) | |
302 ppp_mouse_lock_->MouseLockLost(plugin_->pp_instance()); | |
303 } | |
304 | |
305 private: | |
306 Plugin* plugin_; | |
307 const PPP_MouseLock* ppp_mouse_lock_; | |
308 | |
309 NACL_DISALLOW_COPY_AND_ASSIGN(MouseLockAdapter); | |
310 }; | |
311 | |
312 | |
313 // Derive a class from pp::Printing_Dev to forward PPP_Printing_Dev calls to | |
314 // the plugin. | |
315 class PrintingAdapter : public pp::Printing_Dev { | |
316 public: | |
317 explicit PrintingAdapter(Plugin* plugin) | |
318 : pp::Printing_Dev(plugin), | |
319 plugin_(plugin) { | |
320 BrowserPpp* proxy = plugin_->ppapi_proxy(); | |
321 CHECK(proxy != NULL); | |
322 ppp_printing_ = static_cast<const PPP_Printing_Dev*>( | |
323 proxy->GetPluginInterface(PPP_PRINTING_DEV_INTERFACE)); | |
324 } | |
325 | |
326 uint32_t QuerySupportedPrintOutputFormats() { | |
327 if (ppp_printing_ != NULL) { | |
328 return ppp_printing_->QuerySupportedFormats(plugin_->pp_instance()); | |
329 } | |
330 return 0; | |
331 } | |
332 | |
333 int32_t PrintBegin(const PP_PrintSettings_Dev& print_settings) { | |
334 if (ppp_printing_ != NULL) { | |
335 return ppp_printing_->Begin(plugin_->pp_instance(), &print_settings); | |
336 } | |
337 return 0; | |
338 } | |
339 | |
340 pp::Resource PrintPages(const PP_PrintPageNumberRange_Dev* page_ranges, | |
341 uint32_t page_range_count) { | |
342 if (ppp_printing_ != NULL) { | |
343 PP_Resource image_data = ppp_printing_->PrintPages(plugin_->pp_instance(), | |
344 page_ranges, | |
345 page_range_count); | |
346 return pp::ImageData(pp::PASS_REF, image_data); | |
347 } | |
348 return pp::Resource(); | |
349 } | |
350 | |
351 void PrintEnd() { | |
352 if (ppp_printing_ != NULL) | |
353 ppp_printing_->End(plugin_->pp_instance()); | |
354 } | |
355 | |
356 bool IsPrintScalingDisabled() { | |
357 if (ppp_printing_ != NULL) { | |
358 PP_Bool result = ppp_printing_->IsScalingDisabled(plugin_->pp_instance()); | |
359 return result == PP_TRUE; | |
360 } | |
361 return false; | |
362 } | |
363 | |
364 private: | |
365 Plugin* plugin_; | |
366 const PPP_Printing_Dev* ppp_printing_; | |
367 | |
368 NACL_DISALLOW_COPY_AND_ASSIGN(PrintingAdapter); | |
369 }; | |
370 | |
371 | |
372 // Derive a class from pp::Selection_Dev to forward PPP_Selection_Dev calls to | |
373 // the plugin. | |
374 class SelectionAdapter : public pp::Selection_Dev { | |
375 public: | |
376 explicit SelectionAdapter(Plugin* plugin) | |
377 : pp::Selection_Dev(plugin), | |
378 plugin_(plugin) { | |
379 BrowserPpp* proxy = plugin_->ppapi_proxy(); | |
380 CHECK(proxy != NULL); | |
381 ppp_selection_ = static_cast<const PPP_Selection_Dev*>( | |
382 proxy->GetPluginInterface(PPP_SELECTION_DEV_INTERFACE)); | |
383 } | |
384 | |
385 pp::Var GetSelectedText(bool html) { | |
386 if (ppp_selection_ != NULL) { | |
387 PP_Var var = ppp_selection_->GetSelectedText(plugin_->pp_instance(), | |
388 PP_FromBool(html)); | |
389 return pp::Var(pp::PASS_REF, var); | |
390 } | |
391 return pp::Var(); | |
392 } | |
393 | |
394 private: | |
395 Plugin* plugin_; | |
396 const PPP_Selection_Dev* ppp_selection_; | |
397 | |
398 NACL_DISALLOW_COPY_AND_ASSIGN(SelectionAdapter); | |
399 }; | |
400 | |
401 | |
402 // Derive a class from pp::Zoom_Dev to forward PPP_Zoom_Dev calls to | |
403 // the plugin. | |
404 class ZoomAdapter : public pp::Zoom_Dev { | |
405 public: | |
406 explicit ZoomAdapter(Plugin* plugin) | |
407 : pp::Zoom_Dev(plugin), | |
408 plugin_(plugin) { | |
409 BrowserPpp* proxy = plugin_->ppapi_proxy(); | |
410 CHECK(proxy != NULL); | |
411 ppp_zoom_ = static_cast<const PPP_Zoom_Dev*>( | |
412 proxy->GetPluginInterface(PPP_ZOOM_DEV_INTERFACE)); | |
413 } | |
414 | |
415 void Zoom(double factor, bool text_only) { | |
416 if (ppp_zoom_ != NULL) { | |
417 ppp_zoom_->Zoom(plugin_->pp_instance(), | |
418 factor, | |
419 PP_FromBool(text_only)); | |
420 } | |
421 } | |
422 | |
423 private: | |
424 Plugin* plugin_; | |
425 const PPP_Zoom_Dev* ppp_zoom_; | |
426 | |
427 NACL_DISALLOW_COPY_AND_ASSIGN(ZoomAdapter); | |
428 }; | |
429 | |
430 } // namespace | 240 } // namespace |
431 | 241 |
432 static int const kAbiHeaderBuffer = 256; // must be at least EI_ABIVERSION + 1 | 242 static int const kAbiHeaderBuffer = 256; // must be at least EI_ABIVERSION + 1 |
433 | 243 |
434 void Plugin::AddPropertyGet(const nacl::string& prop_name, | 244 void Plugin::AddPropertyGet(const nacl::string& prop_name, |
435 Plugin::PropertyGetter getter) { | 245 Plugin::PropertyGetter getter) { |
436 PLUGIN_PRINTF(("Plugin::AddPropertyGet (prop_name='%s')\n", | 246 PLUGIN_PRINTF(("Plugin::AddPropertyGet (prop_name='%s')\n", |
437 prop_name.c_str())); | 247 prop_name.c_str())); |
438 property_getters_[nacl::string(prop_name)] = getter; | 248 property_getters_[nacl::string(prop_name)] = getter; |
439 } | 249 } |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
601 bool Plugin::LoadNaClModuleContinuationIntern(ErrorInfo* error_info) { | 411 bool Plugin::LoadNaClModuleContinuationIntern(ErrorInfo* error_info) { |
602 if (!main_subprocess_.StartSrpcServices()) { | 412 if (!main_subprocess_.StartSrpcServices()) { |
603 // The NaCl process probably crashed. On Linux, a crash causes this error, | 413 // The NaCl process probably crashed. On Linux, a crash causes this error, |
604 // while on other platforms, the error is detected below, when we attempt to | 414 // while on other platforms, the error is detected below, when we attempt to |
605 // start the proxy. Report a module initialization error here, to make it | 415 // start the proxy. Report a module initialization error here, to make it |
606 // less confusing for developers. | 416 // less confusing for developers. |
607 error_info->SetReport(ERROR_START_PROXY_MODULE, | 417 error_info->SetReport(ERROR_START_PROXY_MODULE, |
608 "could not initialize module."); | 418 "could not initialize module."); |
609 return false; | 419 return false; |
610 } | 420 } |
611 // Try to start the Chrome IPC-based proxy first. | |
612 PP_NaClResult ipc_result = nacl_interface_->StartPpapiProxy(pp_instance()); | 421 PP_NaClResult ipc_result = nacl_interface_->StartPpapiProxy(pp_instance()); |
613 if (ipc_result == PP_NACL_OK) { | 422 if (ipc_result == PP_NACL_OK) { |
614 // Log the amound of time that has passed between the trusted plugin being | 423 // Log the amound of time that has passed between the trusted plugin being |
615 // initialized and the untrusted plugin being initialized. This is | 424 // initialized and the untrusted plugin being initialized. This is |
616 // (roughly) the cost of using NaCl, in terms of startup time. | 425 // (roughly) the cost of using NaCl, in terms of startup time. |
617 HistogramStartupTimeMedium( | 426 HistogramStartupTimeMedium( |
618 "NaCl.Perf.StartupTime.NaClOverhead", | 427 "NaCl.Perf.StartupTime.NaClOverhead", |
619 static_cast<float>(NaClGetTimeOfDayMicroseconds() - init_time_) | 428 static_cast<float>(NaClGetTimeOfDayMicroseconds() - init_time_) |
620 / NACL_MICROS_PER_MILLI); | 429 / NACL_MICROS_PER_MILLI); |
621 } else if (ipc_result == PP_NACL_USE_SRPC) { | |
622 // Start the old SRPC PPAPI proxy. | |
623 if (!main_subprocess_.StartJSObjectProxy(this, error_info)) { | |
624 return false; | |
625 } | |
626 } else if (ipc_result == PP_NACL_ERROR_MODULE) { | 430 } else if (ipc_result == PP_NACL_ERROR_MODULE) { |
627 error_info->SetReport(ERROR_START_PROXY_MODULE, | 431 error_info->SetReport(ERROR_START_PROXY_MODULE, |
628 "could not initialize module."); | 432 "could not initialize module."); |
629 return false; | 433 return false; |
630 } else if (ipc_result == PP_NACL_ERROR_INSTANCE) { | 434 } else if (ipc_result == PP_NACL_ERROR_INSTANCE) { |
631 error_info->SetReport(ERROR_START_PROXY_INSTANCE, | 435 error_info->SetReport(ERROR_START_PROXY_INSTANCE, |
632 "could not create instance."); | 436 "could not create instance."); |
633 return false; | 437 return false; |
634 } | 438 } |
635 PLUGIN_PRINTF(("Plugin::LoadNaClModule (%s)\n", | 439 PLUGIN_PRINTF(("Plugin::LoadNaClModule (%s)\n", |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
849 : pp::InstancePrivate(pp_instance), | 653 : pp::InstancePrivate(pp_instance), |
850 scriptable_plugin_(NULL), | 654 scriptable_plugin_(NULL), |
851 argc_(-1), | 655 argc_(-1), |
852 argn_(NULL), | 656 argn_(NULL), |
853 argv_(NULL), | 657 argv_(NULL), |
854 main_subprocess_("main subprocess", NULL, NULL), | 658 main_subprocess_("main subprocess", NULL, NULL), |
855 nacl_ready_state_(UNSENT), | 659 nacl_ready_state_(UNSENT), |
856 nexe_error_reported_(false), | 660 nexe_error_reported_(false), |
857 wrapper_factory_(NULL), | 661 wrapper_factory_(NULL), |
858 last_error_string_(""), | 662 last_error_string_(""), |
859 ppapi_proxy_(NULL), | |
860 enable_dev_interfaces_(false), | 663 enable_dev_interfaces_(false), |
861 init_time_(0), | 664 init_time_(0), |
862 ready_time_(0), | 665 ready_time_(0), |
863 nexe_size_(0), | 666 nexe_size_(0), |
864 time_of_last_progress_event_(0), | 667 time_of_last_progress_event_(0), |
865 nacl_interface_(NULL) { | 668 nacl_interface_(NULL) { |
866 PLUGIN_PRINTF(("Plugin::Plugin (this=%p, pp_instance=%" | 669 PLUGIN_PRINTF(("Plugin::Plugin (this=%p, pp_instance=%" |
867 NACL_PRId32")\n", static_cast<void*>(this), pp_instance)); | 670 NACL_PRId32")\n", static_cast<void*>(this), pp_instance)); |
868 callback_factory_.Initialize(this); | 671 callback_factory_.Initialize(this); |
869 nexe_downloader_.Initialize(this); | 672 nexe_downloader_.Initialize(this); |
870 nacl_interface_ = GetNaClInterface(); | 673 nacl_interface_ = GetNaClInterface(); |
871 CHECK(nacl_interface_ != NULL); | 674 CHECK(nacl_interface_ != NULL); |
872 } | 675 } |
873 | 676 |
874 | 677 |
875 Plugin::~Plugin() { | 678 Plugin::~Plugin() { |
876 int64_t shutdown_start = NaClGetTimeOfDayMicroseconds(); | 679 int64_t shutdown_start = NaClGetTimeOfDayMicroseconds(); |
877 | 680 |
878 PLUGIN_PRINTF(("Plugin::~Plugin (this=%p, scriptable_plugin=%p)\n", | 681 PLUGIN_PRINTF(("Plugin::~Plugin (this=%p, scriptable_plugin=%p)\n", |
879 static_cast<void*>(this), | 682 static_cast<void*>(this), |
880 static_cast<void*>(scriptable_plugin()))); | 683 static_cast<void*>(scriptable_plugin()))); |
881 // Destroy the coordinator while the rest of the data is still there | 684 // Destroy the coordinator while the rest of the data is still there |
882 pnacl_coordinator_.reset(NULL); | 685 pnacl_coordinator_.reset(NULL); |
883 // If the proxy has been shutdown before now, it's likely the plugin suffered | 686 |
884 // an error while loading. | 687 if (!nexe_error_reported()) { |
885 if (ppapi_proxy_ != NULL) { | |
886 HistogramTimeLarge( | 688 HistogramTimeLarge( |
887 "NaCl.ModuleUptime.Normal", | 689 "NaCl.ModuleUptime.Normal", |
888 (shutdown_start - ready_time_) / NACL_MICROS_PER_MILLI); | 690 (shutdown_start - ready_time_) / NACL_MICROS_PER_MILLI); |
889 } | 691 } |
890 | 692 |
891 url_downloaders_.erase(url_downloaders_.begin(), url_downloaders_.end()); | 693 url_downloaders_.erase(url_downloaders_.begin(), url_downloaders_.end()); |
892 | 694 |
893 ShutdownProxy(); | |
894 ScriptablePlugin* scriptable_plugin_ = scriptable_plugin(); | 695 ScriptablePlugin* scriptable_plugin_ = scriptable_plugin(); |
895 ScriptablePlugin::Unref(&scriptable_plugin_); | 696 ScriptablePlugin::Unref(&scriptable_plugin_); |
896 | 697 |
897 // ShutDownSubprocesses shuts down the main subprocess, which shuts | 698 // ShutDownSubprocesses shuts down the main subprocess, which shuts |
898 // down the main ServiceRuntime object, which kills the subprocess. | 699 // down the main ServiceRuntime object, which kills the subprocess. |
899 // As a side effect of the subprocess being killed, the reverse | 700 // As a side effect of the subprocess being killed, the reverse |
900 // services thread(s) will get EOF on the reverse channel(s), and | 701 // services thread(s) will get EOF on the reverse channel(s), and |
901 // the thread(s) will exit. In ServiceRuntime::Shutdown, we invoke | 702 // the thread(s) will exit. In ServiceRuntime::Shutdown, we invoke |
902 // ReverseService::WaitForServiceThreadsToExit(), so that there will | 703 // ReverseService::WaitForServiceThreadsToExit(), so that there will |
903 // not be an extent thread(s) hanging around. This means that the | 704 // not be an extent thread(s) hanging around. This means that the |
(...skipping 22 matching lines...) Expand all Loading... |
926 | 727 |
927 HistogramTimeSmall( | 728 HistogramTimeSmall( |
928 "NaCl.Perf.ShutdownTime.Total", | 729 "NaCl.Perf.ShutdownTime.Total", |
929 (NaClGetTimeOfDayMicroseconds() - shutdown_start) | 730 (NaClGetTimeOfDayMicroseconds() - shutdown_start) |
930 / NACL_MICROS_PER_MILLI); | 731 / NACL_MICROS_PER_MILLI); |
931 | 732 |
932 PLUGIN_PRINTF(("Plugin::~Plugin (this=%p, return)\n", | 733 PLUGIN_PRINTF(("Plugin::~Plugin (this=%p, return)\n", |
933 static_cast<void*>(this))); | 734 static_cast<void*>(this))); |
934 } | 735 } |
935 | 736 |
936 | |
937 void Plugin::DidChangeView(const pp::View& view) { | |
938 PLUGIN_PRINTF(("Plugin::DidChangeView (this=%p)\n", | |
939 static_cast<void*>(this))); | |
940 | |
941 if (!BrowserPpp::is_valid(ppapi_proxy_)) { | |
942 // Store this event and replay it when the proxy becomes available. | |
943 view_to_replay_ = view; | |
944 } else { | |
945 ppapi_proxy_->ppp_instance_interface()->DidChangeView( | |
946 pp_instance(), view.pp_resource()); | |
947 } | |
948 } | |
949 | |
950 | |
951 void Plugin::DidChangeFocus(bool has_focus) { | |
952 PLUGIN_PRINTF(("Plugin::DidChangeFocus (this=%p)\n", | |
953 static_cast<void*>(this))); | |
954 if (BrowserPpp::is_valid(ppapi_proxy_)) { | |
955 ppapi_proxy_->ppp_instance_interface()->DidChangeFocus( | |
956 pp_instance(), PP_FromBool(has_focus)); | |
957 } | |
958 } | |
959 | |
960 | |
961 bool Plugin::HandleInputEvent(const pp::InputEvent& event) { | |
962 PLUGIN_PRINTF(("Plugin::HandleInputEvent (this=%p)\n", | |
963 static_cast<void*>(this))); | |
964 if (!BrowserPpp::is_valid(ppapi_proxy_) || | |
965 ppapi_proxy_->ppp_input_event_interface() == NULL) { | |
966 return false; // event is not handled here. | |
967 } else { | |
968 bool handled = PP_ToBool( | |
969 ppapi_proxy_->ppp_input_event_interface()->HandleInputEvent( | |
970 pp_instance(), event.pp_resource())); | |
971 PLUGIN_PRINTF(("Plugin::HandleInputEvent (handled=%d)\n", handled)); | |
972 return handled; | |
973 } | |
974 } | |
975 | |
976 | |
977 bool Plugin::HandleDocumentLoad(const pp::URLLoader& url_loader) { | 737 bool Plugin::HandleDocumentLoad(const pp::URLLoader& url_loader) { |
978 PLUGIN_PRINTF(("Plugin::HandleDocumentLoad (this=%p)\n", | 738 PLUGIN_PRINTF(("Plugin::HandleDocumentLoad (this=%p)\n", |
979 static_cast<void*>(this))); | 739 static_cast<void*>(this))); |
980 if (!BrowserPpp::is_valid(ppapi_proxy_)) { | 740 // We don't know if the plugin will handle the document load, but return |
981 // Store this event and replay it when the proxy becomes available. | 741 // true in order to give it a chance to respond once the proxy is started. |
982 document_load_to_replay_ = url_loader; | 742 return true; |
983 // Return true so that the browser keeps servicing this loader so we can | |
984 // perform requests on it later. | |
985 return true; | |
986 } else { | |
987 return PP_ToBool( | |
988 ppapi_proxy_->ppp_instance_interface()->HandleDocumentLoad( | |
989 pp_instance(), url_loader.pp_resource())); | |
990 } | |
991 } | 743 } |
992 | 744 |
993 | |
994 void Plugin::HandleMessage(const pp::Var& message) { | |
995 PLUGIN_PRINTF(("Plugin::HandleMessage (this=%p)\n", | |
996 static_cast<void*>(this))); | |
997 if (BrowserPpp::is_valid(ppapi_proxy_) && | |
998 ppapi_proxy_->ppp_messaging_interface() != NULL) { | |
999 ppapi_proxy_->ppp_messaging_interface()->HandleMessage( | |
1000 pp_instance(), message.pp_var()); | |
1001 } | |
1002 } | |
1003 | |
1004 | |
1005 pp::Var Plugin::GetInstanceObject() { | 745 pp::Var Plugin::GetInstanceObject() { |
1006 PLUGIN_PRINTF(("Plugin::GetInstanceObject (this=%p)\n", | 746 PLUGIN_PRINTF(("Plugin::GetInstanceObject (this=%p)\n", |
1007 static_cast<void*>(this))); | 747 static_cast<void*>(this))); |
1008 // The browser will unref when it discards the var for this object. | 748 // The browser will unref when it discards the var for this object. |
1009 ScriptablePlugin* handle = | 749 ScriptablePlugin* handle = |
1010 static_cast<ScriptablePlugin*>(scriptable_plugin()->AddRef()); | 750 static_cast<ScriptablePlugin*>(scriptable_plugin()->AddRef()); |
1011 pp::Var* handle_var = handle->var(); | 751 pp::Var* handle_var = handle->var(); |
1012 PLUGIN_PRINTF(("Plugin::GetInstanceObject (handle=%p, handle_var=%p)\n", | 752 PLUGIN_PRINTF(("Plugin::GetInstanceObject (handle=%p, handle_var=%p)\n", |
1013 static_cast<void*>(handle), static_cast<void*>(handle_var))); | 753 static_cast<void*>(handle), static_cast<void*>(handle_var))); |
1014 return *handle_var; // make a copy | 754 return *handle_var; // make a copy |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1164 if (nexe_error_reported()) { | 904 if (nexe_error_reported()) { |
1165 PLUGIN_PRINTF(("Plugin::NexeDidCrash: error already reported;" | 905 PLUGIN_PRINTF(("Plugin::NexeDidCrash: error already reported;" |
1166 " suppressing\n")); | 906 " suppressing\n")); |
1167 } else { | 907 } else { |
1168 if (nacl_ready_state() == DONE) { | 908 if (nacl_ready_state() == DONE) { |
1169 ReportDeadNexe(); | 909 ReportDeadNexe(); |
1170 } else { | 910 } else { |
1171 ErrorInfo error_info; | 911 ErrorInfo error_info; |
1172 // The error is not quite right. In particular, the crash | 912 // The error is not quite right. In particular, the crash |
1173 // reported by this path could be due to NaCl application | 913 // reported by this path could be due to NaCl application |
1174 // crashes that occur after the pepper proxy has started. | 914 // crashes that occur after the PPAPI proxy has started. |
1175 error_info.SetReport(ERROR_START_PROXY_CRASH, | 915 error_info.SetReport(ERROR_START_PROXY_CRASH, |
1176 "Nexe crashed during startup"); | 916 "Nexe crashed during startup"); |
1177 ReportLoadError(error_info); | 917 ReportLoadError(error_info); |
1178 } | 918 } |
1179 } | 919 } |
1180 | 920 |
1181 // In all cases, try to grab the crash log. The first error | 921 // In all cases, try to grab the crash log. The first error |
1182 // reported may have come from the start_module RPC reply indicating | 922 // reported may have come from the start_module RPC reply indicating |
1183 // a validation error or something similar, which wouldn't grab the | 923 // a validation error or something similar, which wouldn't grab the |
1184 // crash log. In the event that this is called twice, the second | 924 // crash log. In the event that this is called twice, the second |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1223 UNREFERENCED_PARAMETER(pp_error); | 963 UNREFERENCED_PARAMETER(pp_error); |
1224 if (was_successful) { | 964 if (was_successful) { |
1225 ReportLoadSuccess(LENGTH_IS_NOT_COMPUTABLE, | 965 ReportLoadSuccess(LENGTH_IS_NOT_COMPUTABLE, |
1226 kUnknownBytes, | 966 kUnknownBytes, |
1227 kUnknownBytes); | 967 kUnknownBytes); |
1228 } else { | 968 } else { |
1229 ReportLoadError(error_info); | 969 ReportLoadError(error_info); |
1230 } | 970 } |
1231 } | 971 } |
1232 | 972 |
1233 bool Plugin::StartProxiedExecution(NaClSrpcChannel* srpc_channel, | |
1234 ErrorInfo* error_info) { | |
1235 PLUGIN_PRINTF(("Plugin::StartProxiedExecution (srpc_channel=%p)\n", | |
1236 static_cast<void*>(srpc_channel))); | |
1237 | |
1238 // Log the amound of time that has passed between the trusted plugin being | |
1239 // initialized and the untrusted plugin being initialized. This is (roughly) | |
1240 // the cost of using NaCl, in terms of startup time. | |
1241 HistogramStartupTimeMedium( | |
1242 "NaCl.Perf.StartupTime.NaClOverhead", | |
1243 static_cast<float>(NaClGetTimeOfDayMicroseconds() - init_time_) | |
1244 / NACL_MICROS_PER_MILLI); | |
1245 | |
1246 // Check that the .nexe exports the PPAPI intialization method. | |
1247 NaClSrpcService* client_service = srpc_channel->client; | |
1248 if (NaClSrpcServiceMethodIndex(client_service, | |
1249 "PPP_InitializeModule:ihs:i") == | |
1250 kNaClSrpcInvalidMethodIndex) { | |
1251 error_info->SetReport( | |
1252 ERROR_START_PROXY_CHECK_PPP, | |
1253 "could not find PPP_InitializeModule() - toolchain version mismatch?"); | |
1254 PLUGIN_PRINTF(("Plugin::StartProxiedExecution (%s)\n", | |
1255 error_info->message().c_str())); | |
1256 return false; | |
1257 } | |
1258 nacl::scoped_ptr<BrowserPpp> ppapi_proxy(new BrowserPpp(srpc_channel, this)); | |
1259 PLUGIN_PRINTF(("Plugin::StartProxiedExecution (ppapi_proxy=%p)\n", | |
1260 static_cast<void*>(ppapi_proxy.get()))); | |
1261 if (ppapi_proxy.get() == NULL) { | |
1262 error_info->SetReport(ERROR_START_PROXY_ALLOC, | |
1263 "could not allocate proxy memory."); | |
1264 return false; | |
1265 } | |
1266 pp::Module* module = pp::Module::Get(); | |
1267 PLUGIN_PRINTF(("Plugin::StartProxiedExecution (module=%p)\n", | |
1268 static_cast<void*>(module))); | |
1269 CHECK(module != NULL); // We could not have gotten past init stage otherwise. | |
1270 int32_t pp_error = | |
1271 ppapi_proxy->InitializeModule(module->pp_module(), | |
1272 module->get_browser_interface()); | |
1273 PLUGIN_PRINTF(("Plugin::StartProxiedExecution (pp_error=%" | |
1274 NACL_PRId32")\n", pp_error)); | |
1275 if (pp_error != PP_OK) { | |
1276 error_info->SetReport(ERROR_START_PROXY_MODULE, | |
1277 "could not initialize module."); | |
1278 return false; | |
1279 } | |
1280 const PPP_Instance* instance_interface = | |
1281 ppapi_proxy->ppp_instance_interface(); | |
1282 PLUGIN_PRINTF(("Plugin::StartProxiedExecution (ppp_instance=%p)\n", | |
1283 static_cast<const void*>(instance_interface))); | |
1284 CHECK(instance_interface != NULL); // Verified on module initialization. | |
1285 PP_Bool did_create = instance_interface->DidCreate( | |
1286 pp_instance(), | |
1287 argc(), | |
1288 const_cast<const char**>(argn()), | |
1289 const_cast<const char**>(argv())); | |
1290 PLUGIN_PRINTF(("Plugin::StartProxiedExecution (did_create=%d)\n", | |
1291 did_create)); | |
1292 if (did_create == PP_FALSE) { | |
1293 error_info->SetReport(ERROR_START_PROXY_INSTANCE, | |
1294 "could not create instance."); | |
1295 return false; | |
1296 } | |
1297 | |
1298 ppapi_proxy_ = ppapi_proxy.release(); | |
1299 | |
1300 // Create PPP* interface adapters to forward calls to .nexe. | |
1301 find_adapter_.reset(new FindAdapter(this)); | |
1302 mouse_lock_adapter_.reset(new MouseLockAdapter(this)); | |
1303 printing_adapter_.reset(new PrintingAdapter(this)); | |
1304 selection_adapter_.reset(new SelectionAdapter(this)); | |
1305 zoom_adapter_.reset(new ZoomAdapter(this)); | |
1306 | |
1307 // Replay missed events. | |
1308 if (!view_to_replay_.is_null()) { | |
1309 DidChangeView(view_to_replay_); | |
1310 view_to_replay_ = pp::View(); | |
1311 } | |
1312 if (!document_load_to_replay_.is_null()) { | |
1313 HandleDocumentLoad(document_load_to_replay_); | |
1314 document_load_to_replay_ = pp::URLLoader(); | |
1315 } | |
1316 bool is_valid_proxy = BrowserPpp::is_valid(ppapi_proxy_); | |
1317 PLUGIN_PRINTF(("Plugin::StartProxiedExecution (is_valid_proxy=%d)\n", | |
1318 is_valid_proxy)); | |
1319 if (!is_valid_proxy) { | |
1320 error_info->SetReport(ERROR_START_PROXY_CRASH, | |
1321 "instance crashed after creation."); | |
1322 } | |
1323 return is_valid_proxy; | |
1324 } | |
1325 | |
1326 void Plugin::ReportDeadNexe() { | 973 void Plugin::ReportDeadNexe() { |
1327 PLUGIN_PRINTF(("Plugin::ReportDeadNexe\n")); | 974 PLUGIN_PRINTF(("Plugin::ReportDeadNexe\n")); |
1328 if (ppapi_proxy_ != NULL) | |
1329 ppapi_proxy_->ReportDeadNexe(); | |
1330 | 975 |
1331 if (nacl_ready_state() == DONE && !nexe_error_reported()) { // After loadEnd. | 976 if (nacl_ready_state() == DONE && !nexe_error_reported()) { // After loadEnd. |
1332 int64_t crash_time = NaClGetTimeOfDayMicroseconds(); | 977 int64_t crash_time = NaClGetTimeOfDayMicroseconds(); |
1333 // Crashes will be more likely near startup, so use a medium histogram | 978 // Crashes will be more likely near startup, so use a medium histogram |
1334 // instead of a large one. | 979 // instead of a large one. |
1335 HistogramTimeMedium( | 980 HistogramTimeMedium( |
1336 "NaCl.ModuleUptime.Crash", | 981 "NaCl.ModuleUptime.Crash", |
1337 (crash_time - ready_time_) / NACL_MICROS_PER_MILLI); | 982 (crash_time - ready_time_) / NACL_MICROS_PER_MILLI); |
1338 | 983 |
1339 nacl::string message = nacl::string("NaCl module crashed"); | 984 nacl::string message = nacl::string("NaCl module crashed"); |
1340 set_last_error_string(message); | 985 set_last_error_string(message); |
1341 AddToConsole(message); | 986 AddToConsole(message); |
1342 | 987 |
1343 EnqueueProgressEvent(kProgressEventCrash); | 988 EnqueueProgressEvent(kProgressEventCrash); |
1344 set_nexe_error_reported(true); | 989 set_nexe_error_reported(true); |
1345 CHECK(ppapi_proxy_ == NULL || !ppapi_proxy_->is_valid()); | |
1346 ShutdownProxy(); | |
1347 } | 990 } |
1348 // else ReportLoadError() and ReportAbortError() will be used by loading code | 991 // else ReportLoadError() and ReportAbortError() will be used by loading code |
1349 // to provide error handling and proxy shutdown. | 992 // to provide error handling. |
1350 // | 993 // |
1351 // NOTE: not all crashes during load will make it here. | 994 // NOTE: not all crashes during load will make it here. |
1352 // Those in BrowserPpp::InitializeModule and creation of PPP interfaces | 995 // Those in BrowserPpp::InitializeModule and creation of PPP interfaces |
1353 // will just get reported back as PP_ERROR_FAILED. | 996 // will just get reported back as PP_ERROR_FAILED. |
1354 } | 997 } |
1355 | 998 |
1356 void Plugin::ShutdownProxy() { | |
1357 PLUGIN_PRINTF(("Plugin::ShutdownProxy (ppapi_proxy=%p)\n", | |
1358 static_cast<void*>(ppapi_proxy_))); | |
1359 // We do not call remote PPP_Instance::DidDestroy because the untrusted | |
1360 // side can no longer take full advantage of mostly asynchronous Pepper | |
1361 // per-Instance interfaces at this point. | |
1362 if (ppapi_proxy_ != NULL) { | |
1363 ppapi_proxy_->ShutdownModule(); | |
1364 delete ppapi_proxy_; | |
1365 ppapi_proxy_ = NULL; | |
1366 } | |
1367 } | |
1368 | |
1369 void Plugin::NaClManifestBufferReady(int32_t pp_error) { | 999 void Plugin::NaClManifestBufferReady(int32_t pp_error) { |
1370 PLUGIN_PRINTF(("Plugin::NaClManifestBufferReady (pp_error=%" | 1000 PLUGIN_PRINTF(("Plugin::NaClManifestBufferReady (pp_error=%" |
1371 NACL_PRId32")\n", pp_error)); | 1001 NACL_PRId32")\n", pp_error)); |
1372 ErrorInfo error_info; | 1002 ErrorInfo error_info; |
1373 set_manifest_url(nexe_downloader_.url()); | 1003 set_manifest_url(nexe_downloader_.url()); |
1374 if (pp_error != PP_OK) { | 1004 if (pp_error != PP_OK) { |
1375 if (pp_error == PP_ERROR_ABORTED) { | 1005 if (pp_error == PP_ERROR_ABORTED) { |
1376 ReportLoadAbort(); | 1006 ReportLoadAbort(); |
1377 } else { | 1007 } else { |
1378 error_info.SetReport(ERROR_MANIFEST_LOAD_URL, | 1008 error_info.SetReport(ERROR_MANIFEST_LOAD_URL, |
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1701 } | 1331 } |
1702 | 1332 |
1703 // Set the readyState attribute to indicate we need to start over. | 1333 // Set the readyState attribute to indicate we need to start over. |
1704 set_nacl_ready_state(DONE); | 1334 set_nacl_ready_state(DONE); |
1705 set_nexe_error_reported(true); | 1335 set_nexe_error_reported(true); |
1706 // Report an error in lastError and on the JavaScript console. | 1336 // Report an error in lastError and on the JavaScript console. |
1707 nacl::string message = nacl::string("NaCl module load failed: ") + | 1337 nacl::string message = nacl::string("NaCl module load failed: ") + |
1708 error_info.message(); | 1338 error_info.message(); |
1709 set_last_error_string(message); | 1339 set_last_error_string(message); |
1710 AddToConsole(message); | 1340 AddToConsole(message); |
1711 ShutdownProxy(); | |
1712 // Inform JavaScript that loading encountered an error and is complete. | 1341 // Inform JavaScript that loading encountered an error and is complete. |
1713 EnqueueProgressEvent(kProgressEventError); | 1342 EnqueueProgressEvent(kProgressEventError); |
1714 EnqueueProgressEvent(kProgressEventLoadEnd); | 1343 EnqueueProgressEvent(kProgressEventLoadEnd); |
1715 | 1344 |
1716 // UMA | 1345 // UMA |
1717 HistogramEnumerateLoadStatus(error_info.error_code()); | 1346 HistogramEnumerateLoadStatus(error_info.error_code()); |
1718 } | 1347 } |
1719 | 1348 |
1720 | 1349 |
1721 void Plugin::ReportLoadAbort() { | 1350 void Plugin::ReportLoadAbort() { |
1722 PLUGIN_PRINTF(("Plugin::ReportLoadAbort\n")); | 1351 PLUGIN_PRINTF(("Plugin::ReportLoadAbort\n")); |
1723 // Set the readyState attribute to indicate we need to start over. | 1352 // Set the readyState attribute to indicate we need to start over. |
1724 set_nacl_ready_state(DONE); | 1353 set_nacl_ready_state(DONE); |
1725 set_nexe_error_reported(true); | 1354 set_nexe_error_reported(true); |
1726 // Report an error in lastError and on the JavaScript console. | 1355 // Report an error in lastError and on the JavaScript console. |
1727 nacl::string error_string("NaCl module load failed: user aborted"); | 1356 nacl::string error_string("NaCl module load failed: user aborted"); |
1728 set_last_error_string(error_string); | 1357 set_last_error_string(error_string); |
1729 AddToConsole(error_string); | 1358 AddToConsole(error_string); |
1730 ShutdownProxy(); | |
1731 // Inform JavaScript that loading was aborted and is complete. | 1359 // Inform JavaScript that loading was aborted and is complete. |
1732 EnqueueProgressEvent(kProgressEventAbort); | 1360 EnqueueProgressEvent(kProgressEventAbort); |
1733 EnqueueProgressEvent(kProgressEventLoadEnd); | 1361 EnqueueProgressEvent(kProgressEventLoadEnd); |
1734 | 1362 |
1735 // UMA | 1363 // UMA |
1736 HistogramEnumerateLoadStatus(ERROR_LOAD_ABORTED); | 1364 HistogramEnumerateLoadStatus(ERROR_LOAD_ABORTED); |
1737 } | 1365 } |
1738 | 1366 |
1739 void Plugin::UpdateDownloadProgress( | 1367 void Plugin::UpdateDownloadProgress( |
1740 PP_Instance pp_instance, | 1368 PP_Instance pp_instance, |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1941 static_cast<uint32_t>(text.size())); | 1569 static_cast<uint32_t>(text.size())); |
1942 const PPB_Console* console_interface = | 1570 const PPB_Console* console_interface = |
1943 static_cast<const PPB_Console*>( | 1571 static_cast<const PPB_Console*>( |
1944 module->GetBrowserInterface(PPB_CONSOLE_INTERFACE)); | 1572 module->GetBrowserInterface(PPB_CONSOLE_INTERFACE)); |
1945 console_interface->LogWithSource(pp_instance(), PP_LOGLEVEL_LOG, prefix, str); | 1573 console_interface->LogWithSource(pp_instance(), PP_LOGLEVEL_LOG, prefix, str); |
1946 var_interface->Release(prefix); | 1574 var_interface->Release(prefix); |
1947 var_interface->Release(str); | 1575 var_interface->Release(str); |
1948 } | 1576 } |
1949 | 1577 |
1950 } // namespace plugin | 1578 } // namespace plugin |
OLD | NEW |