Chromium Code Reviews| 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 22 matching lines...) Expand all Loading... | |
| 33 #include "native_client/src/include/portability_io.h" | 33 #include "native_client/src/include/portability_io.h" |
| 34 #include "native_client/src/include/portability_string.h" | 34 #include "native_client/src/include/portability_string.h" |
| 35 #include "native_client/src/shared/platform/nacl_check.h" | 35 #include "native_client/src/shared/platform/nacl_check.h" |
| 36 #include "native_client/src/shared/platform/nacl_time.h" | 36 #include "native_client/src/shared/platform/nacl_time.h" |
| 37 #include "native_client/src/shared/ppapi_proxy/browser_ppp.h" | 37 #include "native_client/src/shared/ppapi_proxy/browser_ppp.h" |
| 38 #include "native_client/src/trusted/desc/nacl_desc_base.h" | 38 #include "native_client/src/trusted/desc/nacl_desc_base.h" |
| 39 #include "native_client/src/trusted/desc/nacl_desc_conn_cap.h" | 39 #include "native_client/src/trusted/desc/nacl_desc_conn_cap.h" |
| 40 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" | 40 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" |
| 41 #include "native_client/src/trusted/handle_pass/browser_handle.h" | 41 #include "native_client/src/trusted/handle_pass/browser_handle.h" |
| 42 #include "native_client/src/trusted/nonnacl_util/sel_ldr_launcher.h" | 42 #include "native_client/src/trusted/nonnacl_util/sel_ldr_launcher.h" |
| 43 #include "native_client/src/trusted/plugin/browser_interface.h" | |
| 44 #include "native_client/src/trusted/plugin/desc_based_handle.h" | |
| 45 #include "native_client/src/trusted/plugin/json_manifest.h" | 43 #include "native_client/src/trusted/plugin/json_manifest.h" |
| 46 #include "native_client/src/trusted/plugin/nacl_subprocess.h" | 44 #include "native_client/src/trusted/plugin/nacl_subprocess.h" |
| 47 #include "native_client/src/trusted/plugin/nexe_arch.h" | 45 #include "native_client/src/trusted/plugin/nexe_arch.h" |
| 48 #include "native_client/src/trusted/plugin/plugin_error.h" | 46 #include "native_client/src/trusted/plugin/plugin_error.h" |
| 49 #include "native_client/src/trusted/plugin/scriptable_handle.h" | 47 #include "native_client/src/trusted/plugin/scriptable_plugin.h" |
| 50 #include "native_client/src/trusted/plugin/service_runtime.h" | 48 #include "native_client/src/trusted/plugin/service_runtime.h" |
| 51 #include "native_client/src/trusted/plugin/string_encoding.h" | 49 #include "native_client/src/trusted/plugin/string_encoding.h" |
| 52 #include "native_client/src/trusted/plugin/utility.h" | 50 #include "native_client/src/trusted/plugin/utility.h" |
| 53 #include "native_client/src/trusted/service_runtime/include/sys/fcntl.h" | 51 #include "native_client/src/trusted/service_runtime/include/sys/fcntl.h" |
| 54 #include "native_client/src/trusted/service_runtime/nacl_error_code.h" | 52 #include "native_client/src/trusted/service_runtime/nacl_error_code.h" |
| 55 | 53 |
| 54 #include "ppapi/c/dev/ppb_console_dev.h" | |
| 56 #include "ppapi/c/dev/ppp_find_dev.h" | 55 #include "ppapi/c/dev/ppp_find_dev.h" |
| 57 #include "ppapi/c/dev/ppp_printing_dev.h" | 56 #include "ppapi/c/dev/ppp_printing_dev.h" |
| 58 #include "ppapi/c/dev/ppp_scrollbar_dev.h" | 57 #include "ppapi/c/dev/ppp_scrollbar_dev.h" |
| 59 #include "ppapi/c/dev/ppp_selection_dev.h" | 58 #include "ppapi/c/dev/ppp_selection_dev.h" |
| 60 #include "ppapi/c/dev/ppp_widget_dev.h" | 59 #include "ppapi/c/dev/ppp_widget_dev.h" |
| 61 #include "ppapi/c/dev/ppp_zoom_dev.h" | 60 #include "ppapi/c/dev/ppp_zoom_dev.h" |
| 62 #include "ppapi/c/pp_errors.h" | 61 #include "ppapi/c/pp_errors.h" |
| 62 #include "ppapi/c/ppb_var.h" | |
| 63 #include "ppapi/c/ppp_input_event.h" | 63 #include "ppapi/c/ppp_input_event.h" |
| 64 #include "ppapi/c/ppp_instance.h" | 64 #include "ppapi/c/ppp_instance.h" |
| 65 #include "ppapi/c/ppp_mouse_lock.h" | 65 #include "ppapi/c/ppp_mouse_lock.h" |
| 66 #include "ppapi/c/private/ppb_uma_private.h" | 66 #include "ppapi/c/private/ppb_uma_private.h" |
| 67 #include "ppapi/cpp/dev/find_dev.h" | 67 #include "ppapi/cpp/dev/find_dev.h" |
| 68 #include "ppapi/cpp/dev/printing_dev.h" | 68 #include "ppapi/cpp/dev/printing_dev.h" |
| 69 #include "ppapi/cpp/dev/scrollbar_dev.h" | 69 #include "ppapi/cpp/dev/scrollbar_dev.h" |
| 70 #include "ppapi/cpp/dev/selection_dev.h" | 70 #include "ppapi/cpp/dev/selection_dev.h" |
| 71 #include "ppapi/cpp/dev/text_input_dev.h" | 71 #include "ppapi/cpp/dev/text_input_dev.h" |
| 72 #include "ppapi/cpp/dev/url_util_dev.h" | 72 #include "ppapi/cpp/dev/url_util_dev.h" |
| 73 #include "ppapi/cpp/dev/widget_client_dev.h" | 73 #include "ppapi/cpp/dev/widget_client_dev.h" |
| 74 #include "ppapi/cpp/dev/zoom_dev.h" | 74 #include "ppapi/cpp/dev/zoom_dev.h" |
| 75 #include "ppapi/cpp/image_data.h" | 75 #include "ppapi/cpp/image_data.h" |
| 76 #include "ppapi/cpp/input_event.h" | 76 #include "ppapi/cpp/input_event.h" |
| 77 #include "ppapi/cpp/module.h" | 77 #include "ppapi/cpp/module.h" |
| 78 #include "ppapi/cpp/mouse_lock.h" | 78 #include "ppapi/cpp/mouse_lock.h" |
| 79 #include "ppapi/cpp/rect.h" | 79 #include "ppapi/cpp/rect.h" |
| 80 | 80 |
| 81 using ppapi_proxy::BrowserPpp; | 81 using ppapi_proxy::BrowserPpp; |
| 82 | 82 |
| 83 namespace plugin { | 83 namespace plugin { |
| 84 | 84 |
| 85 namespace { | 85 namespace { |
| 86 | 86 |
| 87 bool GetReadyStateProperty(void* obj, SrpcParams* params) { | |
| 88 Plugin* plugin = static_cast<Plugin*>(obj); | |
| 89 params->outs()[0]->u.ival = plugin->nacl_ready_state(); | |
| 90 return true; | |
| 91 } | |
| 92 | |
| 93 const char* const kTypeAttribute = "type"; | 87 const char* const kTypeAttribute = "type"; |
| 94 // The "src" attribute of the <embed> tag. The value is expected to be either | 88 // The "src" attribute of the <embed> tag. The value is expected to be either |
| 95 // a URL or URI pointing to the manifest file (which is expected to contain | 89 // a URL or URI pointing to the manifest file (which is expected to contain |
| 96 // JSON matching ISAs with .nexe URLs). | 90 // JSON matching ISAs with .nexe URLs). |
| 97 const char* const kSrcManifestAttribute = "src"; | 91 const char* const kSrcManifestAttribute = "src"; |
| 98 // The "nacl" attribute of the <embed> tag. We use the value of this attribute | 92 // The "nacl" attribute of the <embed> tag. We use the value of this attribute |
| 99 // to find the manifest file when NaCl is registered as a plug-in for another | 93 // to find the manifest file when NaCl is registered as a plug-in for another |
| 100 // MIME type because the "src" attribute is used to supply us with the resource | 94 // MIME type because the "src" attribute is used to supply us with the resource |
| 101 // of that MIME type that we're supposed to display. | 95 // of that MIME type that we're supposed to display. |
| 102 const char* const kNaClManifestAttribute = "nacl"; | 96 const char* const kNaClManifestAttribute = "nacl"; |
| 103 // This is a pretty arbitrary limit on the byte size of the NaCl manfest file. | 97 // This is a pretty arbitrary limit on the byte size of the NaCl manfest file. |
| 104 // Note that the resulting string object has to have at least one byte extra | 98 // Note that the resulting string object has to have at least one byte extra |
| 105 // for the null termination character. | 99 // for the null termination character. |
| 106 const size_t kNaClManifestMaxFileBytes = 1024 * 1024; | 100 const size_t kNaClManifestMaxFileBytes = 1024 * 1024; |
| 107 | 101 |
| 108 // Define an argument name to enable 'dev' interfaces. To make sure it doesn't | 102 // Define an argument name to enable 'dev' interfaces. To make sure it doesn't |
| 109 // collide with any user-defined HTML attribute, make the first character '@'. | 103 // collide with any user-defined HTML attribute, make the first character '@'. |
| 110 const char* const kDevAttribute = "@dev"; | 104 const char* const kDevAttribute = "@dev"; |
| 111 | 105 |
| 112 // URL schemes that we treat in special ways. | 106 // URL schemes that we treat in special ways. |
| 113 const char* const kChromeExtensionUriScheme = "chrome-extension"; | 107 const char* const kChromeExtensionUriScheme = "chrome-extension"; |
| 114 const char* const kDataUriScheme = "data"; | 108 const char* const kDataUriScheme = "data"; |
| 115 | 109 |
| 116 // The key used to find the dictionary nexe URLs in the manifest file. | 110 // The key used to find the dictionary nexe URLs in the manifest file. |
| 117 const char* const kNexesKey = "nexes"; | 111 const char* const kNexesKey = "nexes"; |
| 118 | 112 |
| 119 bool GetLastError(void* obj, SrpcParams* params) { | |
| 120 NaClSrpcArg** outs = params->outs(); | |
| 121 PLUGIN_PRINTF(("GetLastError (obj=%p)\n", obj)); | |
| 122 | |
| 123 Plugin* plugin = static_cast<Plugin*>(obj); | |
| 124 outs[0]->arrays.str = strdup(plugin->last_error_string().c_str()); | |
| 125 return true; | |
| 126 } | |
| 127 | |
| 128 bool GetExitStatus(void* obj, SrpcParams* params) { | |
| 129 NaClSrpcArg** outs = params->outs(); | |
| 130 PLUGIN_PRINTF(("GetExitStatus (obj=%p)\n", obj)); | |
| 131 | |
| 132 Plugin* plugin = static_cast<Plugin*>(obj); | |
| 133 outs[0]->u.ival = plugin->exit_status(); | |
| 134 return true; | |
| 135 } | |
| 136 | |
| 137 // Up to 20 seconds | 113 // Up to 20 seconds |
| 138 const int64_t kTimeSmallMin = 1; // in ms | 114 const int64_t kTimeSmallMin = 1; // in ms |
| 139 const int64_t kTimeSmallMax = 20000; // in ms | 115 const int64_t kTimeSmallMax = 20000; // in ms |
| 140 const uint32_t kTimeSmallBuckets = 100; | 116 const uint32_t kTimeSmallBuckets = 100; |
| 141 | 117 |
| 142 // Up to 3 minutes, 20 seconds | 118 // Up to 3 minutes, 20 seconds |
| 143 const int64_t kTimeMediumMin = 10; // in ms | 119 const int64_t kTimeMediumMin = 10; // in ms |
| 144 const int64_t kTimeMediumMax = 200000; // in ms | 120 const int64_t kTimeMediumMax = 200000; // in ms |
| 145 const uint32_t kTimeMediumBuckets = 100; | 121 const uint32_t kTimeMediumBuckets = 100; |
| 146 | 122 |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 498 | 474 |
| 499 private: | 475 private: |
| 500 Plugin* plugin_; | 476 Plugin* plugin_; |
| 501 const PPP_Zoom_Dev* ppp_zoom_; | 477 const PPP_Zoom_Dev* ppp_zoom_; |
| 502 | 478 |
| 503 NACL_DISALLOW_COPY_AND_ASSIGN(ZoomAdapter); | 479 NACL_DISALLOW_COPY_AND_ASSIGN(ZoomAdapter); |
| 504 }; | 480 }; |
| 505 | 481 |
| 506 } // namespace | 482 } // namespace |
| 507 | 483 |
| 508 bool Plugin::ExperimentalJavaScriptApisAreEnabled() { | 484 static int const kAbiHeaderBuffer = 256; // must be at least EI_ABIVERSION + 1 |
| 509 return getenv("NACL_ENABLE_EXPERIMENTAL_JAVASCRIPT_APIS") != NULL; | 485 |
| 486 void Plugin::AddPropertyGet(const nacl::string& prop_name, | |
| 487 Plugin::PropertyGetter getter) { | |
| 488 PLUGIN_PRINTF(("Plugin::AddPropertyGet (prop_name='%s')\n", | |
| 489 prop_name.c_str())); | |
| 490 property_getters_[nacl::string(prop_name)] = getter; | |
| 510 } | 491 } |
| 511 | 492 |
| 512 static int const kAbiHeaderBuffer = 256; // must be at least EI_ABIVERSION + 1 | 493 bool Plugin::HasProperty(const nacl::string& prop_name) { |
| 513 | 494 PLUGIN_PRINTF(("Plugin::HasProperty (prop_name=%s)\n", |
| 514 void Plugin::LoadMethods() { | 495 prop_name.c_str())); |
| 515 PLUGIN_PRINTF(("Plugin::LoadMethods ()\n")); | 496 return property_getters_[prop_name] != NULL; |
| 516 // Properties implemented by Plugin. | |
| 517 AddPropertyGet(GetReadyStateProperty, "readyState", "i"); | |
| 518 } | 497 } |
| 519 | 498 |
| 520 bool Plugin::HasMethod(uintptr_t method_id, CallType call_type) { | 499 bool Plugin::GetProperty(const nacl::string& prop_name, |
| 521 PLUGIN_PRINTF(("Plugin::HasMethod (method_id=%x)\n", | 500 NaClSrpcArg* prop_value) { |
| 522 static_cast<int>(method_id))); | 501 PLUGIN_PRINTF(("Plugin::GetProperty (prop_name=%s)\n", prop_name.c_str())); |
| 523 if (GetMethodInfo(method_id, call_type)) { | 502 |
| 524 PLUGIN_PRINTF(("true\n")); | 503 PropertyGetter getter = property_getters_[prop_name]; |
| 525 return true; | 504 if (NULL == getter) { |
| 526 } | |
| 527 if (!ExperimentalJavaScriptApisAreEnabled()) { | |
| 528 PLUGIN_PRINTF(("false\n")); | |
| 529 return false; | 505 return false; |
| 530 } | 506 } |
| 531 if (call_type != METHOD_CALL) { | 507 (this->*getter)(prop_value); |
| 532 // SRPC nexes can only export methods. | 508 return true; |
| 533 PLUGIN_PRINTF(("false\n")); | |
| 534 return false; | |
| 535 } | |
| 536 bool has_method = main_subprocess_.HasMethod(method_id); | |
| 537 PLUGIN_PRINTF(("%s\n", (has_method ? "true" : "false"))); | |
| 538 return has_method; | |
| 539 } | 509 } |
| 540 | 510 |
| 541 bool Plugin::InitParams(uintptr_t method_id, | 511 void Plugin::GetExitStatus(NaClSrpcArg* prop_value) { |
| 542 CallType call_type, | 512 PLUGIN_PRINTF(("GetExitStatus (this=%p)\n", reinterpret_cast<void*>(this))); |
| 543 SrpcParams* params) { | 513 prop_value->tag = NACL_SRPC_ARG_TYPE_INT; |
| 544 MethodInfo* method_info = GetMethodInfo(method_id, call_type); | 514 prop_value->u.ival = exit_status(); |
| 545 PLUGIN_PRINTF(("Plugin::InitParams (id=%"NACL_PRIxPTR", method_info=%p)\n", | |
| 546 method_id, method_info)); | |
| 547 if (NULL != method_info) { | |
| 548 return params->Init(method_info->ins(), method_info->outs()); | |
| 549 } | |
| 550 if (!ExperimentalJavaScriptApisAreEnabled()) { | |
| 551 return false; | |
| 552 } | |
| 553 if (call_type != METHOD_CALL) { | |
| 554 // SRPC nexes can only export methods. | |
| 555 return false; | |
| 556 } | |
| 557 return main_subprocess_.InitParams(method_id, params); | |
| 558 } | 515 } |
| 559 | 516 |
| 560 bool Plugin::Invoke(uintptr_t method_id, | 517 void Plugin::GetLastError(NaClSrpcArg* prop_value) { |
| 561 CallType call_type, | 518 PLUGIN_PRINTF(("GetLastError (this=%p)\n", reinterpret_cast<void*>(this))); |
| 562 SrpcParams* params) { | 519 prop_value->tag = NACL_SRPC_ARG_TYPE_STRING; |
| 563 MethodInfo* method_info = GetMethodInfo(method_id, call_type); | 520 prop_value->arrays.str = strdup(last_error_string().c_str()); |
| 564 | |
| 565 if (NULL != method_info && NULL != method_info->function_ptr()) { | |
| 566 return method_info->function_ptr()(static_cast<void*>(this), params); | |
| 567 } | |
| 568 if (!ExperimentalJavaScriptApisAreEnabled()) { | |
| 569 return false; | |
| 570 } | |
| 571 if (call_type != METHOD_CALL) { | |
| 572 // SRPC nexes can only export methods. | |
| 573 return false; | |
| 574 } | |
| 575 return main_subprocess_.Invoke(method_id, params); | |
| 576 } | 521 } |
| 577 | 522 |
| 578 bool Plugin::Init(BrowserInterface* browser_interface, | 523 void Plugin::GetReadyStateProperty(NaClSrpcArg* prop_value) { |
| 579 int argc, | 524 PLUGIN_PRINTF(("GetReadyState (this=%p)\n", reinterpret_cast<void*>(this))); |
| 580 char* argn[], | 525 prop_value->tag = NACL_SRPC_ARG_TYPE_INT; |
| 581 char* argv[]) { | 526 prop_value->u.ival = nacl_ready_state(); |
| 527 } | |
| 528 | |
| 529 bool Plugin::Init(int argc, char* argn[], char* argv[]) { | |
| 582 PLUGIN_PRINTF(("Plugin::Init (instance=%p)\n", static_cast<void*>(this))); | 530 PLUGIN_PRINTF(("Plugin::Init (instance=%p)\n", static_cast<void*>(this))); |
| 583 | 531 |
| 584 #ifdef NACL_OSX | 532 #ifdef NACL_OSX |
| 585 // TODO(kochi): For crbug.com/102808, this is a stopgap solution for Lion | 533 // TODO(kochi): For crbug.com/102808, this is a stopgap solution for Lion |
| 586 // until we expose IME API to .nexe. This disables any IME interference | 534 // until we expose IME API to .nexe. This disables any IME interference |
| 587 // against key inputs, so you cannot use off-the-spot IME input for NaCl apps. | 535 // against key inputs, so you cannot use off-the-spot IME input for NaCl apps. |
| 588 // This makes discrepancy among platforms and therefore we should remove | 536 // This makes discrepancy among platforms and therefore we should remove |
| 589 // this hack when IME API is made available. | 537 // this hack when IME API is made available. |
| 590 // The default for non-Mac platforms is still off-the-spot IME mode. | 538 // The default for non-Mac platforms is still off-the-spot IME mode. |
| 591 pp::TextInput_Dev(this).SetTextInputType(PP_TEXTINPUT_TYPE_NONE); | 539 pp::TextInput_Dev(this).SetTextInputType(PP_TEXTINPUT_TYPE_NONE); |
| 592 #endif | 540 #endif |
| 593 | 541 |
| 594 browser_interface_ = browser_interface; | |
| 595 // Remember the embed/object argn/argv pairs. | 542 // Remember the embed/object argn/argv pairs. |
| 596 argn_ = new(std::nothrow) char*[argc]; | 543 argn_ = new(std::nothrow) char*[argc]; |
| 597 argv_ = new(std::nothrow) char*[argc]; | 544 argv_ = new(std::nothrow) char*[argc]; |
| 598 argc_ = 0; | 545 argc_ = 0; |
| 599 for (int i = 0; i < argc; ++i) { | 546 for (int i = 0; i < argc; ++i) { |
| 600 if (NULL != argn_ && NULL != argv_) { | 547 if (NULL != argn_ && NULL != argv_) { |
| 601 argn_[argc_] = strdup(argn[i]); | 548 argn_[argc_] = strdup(argn[i]); |
| 602 argv_[argc_] = strdup(argv[i]); | 549 argv_[argc_] = strdup(argv[i]); |
| 603 if (NULL == argn_[argc_] || NULL == argv_[argc_]) { | 550 if (NULL == argn_[argc_] || NULL == argv_[argc_]) { |
| 604 // Give up on passing arguments. | 551 // Give up on passing arguments. |
| 605 free(argn_[argc_]); | 552 free(argn_[argc_]); |
| 606 free(argv_[argc_]); | 553 free(argv_[argc_]); |
| 607 continue; | 554 continue; |
| 608 } | 555 } |
| 609 ++argc_; | 556 ++argc_; |
| 610 } | 557 } |
| 611 } | 558 } |
| 612 // TODO(sehr): this leaks strings if there is a subsequent failure. | 559 // TODO(sehr): this leaks strings if there is a subsequent failure. |
| 613 | 560 |
| 614 // Set up the factory used to produce DescWrappers. | 561 // Set up the factory used to produce DescWrappers. |
| 615 wrapper_factory_ = new nacl::DescWrapperFactory(); | 562 wrapper_factory_ = new nacl::DescWrapperFactory(); |
| 616 if (NULL == wrapper_factory_) { | 563 if (NULL == wrapper_factory_) { |
| 617 return false; | 564 return false; |
| 618 } | 565 } |
| 619 PLUGIN_PRINTF(("Plugin::Init (wrapper_factory=%p)\n", | 566 PLUGIN_PRINTF(("Plugin::Init (wrapper_factory=%p)\n", |
| 620 static_cast<void*>(wrapper_factory_))); | 567 static_cast<void*>(wrapper_factory_))); |
| 621 | 568 |
| 622 // Set up the scriptable methods for the plugin. | 569 // Export a property to allow us to get the exit status of a nexe. |
| 623 LoadMethods(); | 570 AddPropertyGet("exitStatus", &Plugin::GetExitStatus); |
| 571 // Export a property to allow us to get the last error description. | |
| 572 AddPropertyGet("lastError", &Plugin::GetLastError); | |
| 573 // Export a property to allow us to get the ready state of a nexe during load. | |
| 574 AddPropertyGet("readyState", &Plugin::GetReadyStateProperty); | |
| 624 | 575 |
| 625 PLUGIN_PRINTF(("Plugin::Init (return 1)\n")); | 576 PLUGIN_PRINTF(("Plugin::Init (return 1)\n")); |
| 626 // Return success. | 577 // Return success. |
| 627 return true; | 578 return true; |
| 628 } | 579 } |
| 629 | 580 |
| 630 void Plugin::ShutDownSubprocesses() { | 581 void Plugin::ShutDownSubprocesses() { |
| 631 PLUGIN_PRINTF(("Plugin::ShutDownSubprocesses (this=%p)\n", | 582 PLUGIN_PRINTF(("Plugin::ShutDownSubprocesses (this=%p)\n", |
| 632 static_cast<void*>(this))); | 583 static_cast<void*>(this))); |
| 633 PLUGIN_PRINTF(("Plugin::ShutDownSubprocesses (%s)\n", | 584 PLUGIN_PRINTF(("Plugin::ShutDownSubprocesses (%s)\n", |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 663 bool service_runtime_started = | 614 bool service_runtime_started = |
| 664 new_service_runtime->Start(wrapper, error_info); | 615 new_service_runtime->Start(wrapper, error_info); |
| 665 PLUGIN_PRINTF(("Plugin::LoadNaClModuleCommon (service_runtime_started=%d)\n", | 616 PLUGIN_PRINTF(("Plugin::LoadNaClModuleCommon (service_runtime_started=%d)\n", |
| 666 service_runtime_started)); | 617 service_runtime_started)); |
| 667 if (!service_runtime_started) { | 618 if (!service_runtime_started) { |
| 668 return false; | 619 return false; |
| 669 } | 620 } |
| 670 return true; | 621 return true; |
| 671 } | 622 } |
| 672 | 623 |
| 673 bool Plugin::StartSrpcServicesCommon(NaClSubprocess* subprocess, | |
| 674 ErrorInfo* error_info) { | |
| 675 if (!subprocess->StartSrpcServices()) { | |
| 676 error_info->SetReport(ERROR_SRPC_CONNECTION_FAIL, | |
| 677 "SRPC connection failure for " + | |
| 678 subprocess->description()); | |
| 679 return false; | |
| 680 } | |
| 681 PLUGIN_PRINTF(("Plugin::StartSrpcServicesCommon (established srpc_client " | |
| 682 "%p)\n", | |
| 683 static_cast<void*>(subprocess->srpc_client()))); | |
| 684 return true; | |
| 685 } | |
| 686 | |
| 687 bool Plugin::StartSrpcServices(NaClSubprocess* subprocess, | |
| 688 ErrorInfo* error_info) { | |
| 689 if (!StartSrpcServicesCommon(subprocess, error_info)) { | |
| 690 return false; | |
| 691 } | |
| 692 // TODO(jvoung): This next bit is likely not needed... | |
| 693 // If StartSrpcServices is only in the JS API that is just for SRPC nexes | |
| 694 // (namely __startSrpcServices), then attempts to start the JS proxy | |
| 695 // will fail anyway? | |
| 696 // If that is the case, by removing the following line, | |
| 697 // the StartSrpcServices == StartSrpcServicesCommon. | |
| 698 // We still need this function though, to launch helper SRPC nexes within | |
| 699 // the plugin. | |
| 700 return StartJSObjectProxy(subprocess, error_info); | |
| 701 } | |
| 702 | |
| 703 bool Plugin::StartJSObjectProxy(NaClSubprocess* subprocess, | |
| 704 ErrorInfo* error_info) { | |
| 705 if (!subprocess->StartJSObjectProxy(this, error_info)) { | |
| 706 // TODO(sehr,polina): rename the function and env var | |
| 707 // to ExperimentalJavaScriptApisAreEnabled. | |
| 708 if (error_info->error_code() == ERROR_START_PROXY_CHECK_PPP && | |
| 709 ExperimentalJavaScriptApisAreEnabled()) { | |
| 710 // It is not an error for the proxy to fail to find PPP methods if | |
| 711 // experimental APIs are enabled. This means we have an SRPC nexe. | |
| 712 error_info->Reset(); | |
| 713 } else { | |
| 714 return false; | |
| 715 } | |
| 716 } | |
| 717 return true; | |
| 718 } | |
| 719 | |
| 720 bool Plugin::LoadNaClModule(nacl::DescWrapper* wrapper, | 624 bool Plugin::LoadNaClModule(nacl::DescWrapper* wrapper, |
| 721 ErrorInfo* error_info, | 625 ErrorInfo* error_info, |
| 722 pp::CompletionCallback init_done_cb, | 626 pp::CompletionCallback init_done_cb, |
| 723 pp::CompletionCallback crash_cb) { | 627 pp::CompletionCallback crash_cb) { |
| 724 // Before forking a new sel_ldr process, ensure that we do not leak | 628 // Before forking a new sel_ldr process, ensure that we do not leak |
| 725 // the ServiceRuntime object for an existing subprocess, and that any | 629 // the ServiceRuntime object for an existing subprocess, and that any |
| 726 // associated listener threads do not go unjoined because if they | 630 // associated listener threads do not go unjoined because if they |
| 727 // outlive the Plugin object, they will not be memory safe. | 631 // outlive the Plugin object, they will not be memory safe. |
| 728 ShutDownSubprocesses(); | 632 ShutDownSubprocesses(); |
| 729 if (!LoadNaClModuleCommon(wrapper, &main_subprocess_, manifest_.get(), | 633 if (!LoadNaClModuleCommon(wrapper, &main_subprocess_, manifest_.get(), |
| 730 true, error_info, init_done_cb, crash_cb)) { | 634 true, error_info, init_done_cb, crash_cb)) { |
| 731 return false; | 635 return false; |
| 732 } | 636 } |
| 733 PLUGIN_PRINTF(("Plugin::LoadNaClModule (%s)\n", | 637 PLUGIN_PRINTF(("Plugin::LoadNaClModule (%s)\n", |
| 734 main_subprocess_.detailed_description().c_str())); | 638 main_subprocess_.detailed_description().c_str())); |
| 735 return true; | 639 return true; |
| 736 } | 640 } |
| 737 | 641 |
| 738 bool Plugin::LoadNaClModuleContinuationIntern(ErrorInfo* error_info) { | 642 bool Plugin::LoadNaClModuleContinuationIntern(ErrorInfo* error_info) { |
| 739 if (!(StartSrpcServicesCommon(&main_subprocess_, error_info) | 643 if (!(main_subprocess_.StartSrpcServices() |
|
jvoung - send to chromium...
2012/02/15 19:02:28
Should the error_info be passed along, to note any
sehr (please use chromium)
2012/02/16 01:16:59
I've replaced what was there.
| |
| 740 && StartJSObjectProxy(&main_subprocess_, error_info))) { | 644 && main_subprocess_.StartJSObjectProxy(this, error_info))) { |
| 741 return false; | 645 return false; |
| 742 } | 646 } |
| 743 PLUGIN_PRINTF(("Plugin::LoadNaClModule (%s)\n", | 647 PLUGIN_PRINTF(("Plugin::LoadNaClModule (%s)\n", |
| 744 main_subprocess_.detailed_description().c_str())); | 648 main_subprocess_.detailed_description().c_str())); |
| 745 return true; | 649 return true; |
| 746 } | 650 } |
| 747 | 651 |
| 748 NaClSubprocess* Plugin::LoadHelperNaClModule(nacl::DescWrapper* wrapper, | 652 NaClSubprocess* Plugin::LoadHelperNaClModule(nacl::DescWrapper* wrapper, |
| 749 const Manifest* manifest, | 653 const Manifest* manifest, |
| 750 ErrorInfo* error_info) { | 654 ErrorInfo* error_info) { |
| 751 nacl::scoped_ptr<NaClSubprocess> nacl_subprocess( | 655 nacl::scoped_ptr<NaClSubprocess> nacl_subprocess( |
| 752 new NaClSubprocess("helper module", browser_interface_, NULL, NULL)); | 656 new NaClSubprocess("helper module", NULL, NULL)); |
| 753 if (NULL == nacl_subprocess.get()) { | 657 if (NULL == nacl_subprocess.get()) { |
| 754 error_info->SetReport(ERROR_SEL_LDR_INIT, | 658 error_info->SetReport(ERROR_SEL_LDR_INIT, |
| 755 "unable to allocate helper subprocess."); | 659 "unable to allocate helper subprocess."); |
| 756 return NULL; | 660 return NULL; |
| 757 } | 661 } |
| 758 | 662 |
| 759 // Do not report UMA stats for translator-related nexes. | 663 // Do not report UMA stats for translator-related nexes. |
| 760 // TODO(sehr): define new UMA stats for translator related nexe events. | 664 // TODO(sehr): define new UMA stats for translator related nexe events. |
| 761 if (!(LoadNaClModuleCommon(wrapper, nacl_subprocess.get(), manifest, | 665 if (!(LoadNaClModuleCommon(wrapper, nacl_subprocess.get(), manifest, |
| 762 false, error_info, | 666 false, error_info, |
| 763 pp::BlockUntilComplete(), | 667 pp::BlockUntilComplete(), |
| 764 pp::BlockUntilComplete()) | 668 pp::BlockUntilComplete()) |
| 765 // We need not wait for the init_done callback. We can block | 669 // We need not wait for the init_done callback. We can block |
| 766 // here in StartSrpcServicesCommon, since helper NaCl modules | 670 // here in StartSrpcServices, since helper NaCl modules |
| 767 // are spawned from a private thread. | 671 // are spawned from a private thread. |
| 768 // | 672 // |
| 769 // TODO(bsy): if helper module crashes, we should abort. | 673 // TODO(bsy): if helper module crashes, we should abort. |
| 770 // crash_cb is not used here, so we are relying on crashes | 674 // crash_cb is not used here, so we are relying on crashes |
| 771 // being detected in StartSrpcServicesCommon or later. | 675 // being detected in StartSrpcServices or later. |
| 772 // | 676 // |
| 773 // NB: More refactoring might be needed, however, if helper | 677 // NB: More refactoring might be needed, however, if helper |
| 774 // NaCl modules have their own manifest. Currently the | 678 // NaCl modules have their own manifest. Currently the |
| 775 // manifest is a per-plugin-instance object, not a per | 679 // manifest is a per-plugin-instance object, not a per |
| 776 // NaClSubprocess object. | 680 // NaClSubprocess object. |
| 777 && StartSrpcServicesCommon(nacl_subprocess.get(), error_info))) { | 681 && nacl_subprocess->StartSrpcServices())) { |
|
jvoung - send to chromium...
2012/02/15 19:02:28
same
sehr (please use chromium)
2012/02/16 01:16:59
Done.
| |
| 778 return NULL; | 682 return NULL; |
| 779 } | 683 } |
| 780 | 684 |
| 781 PLUGIN_PRINTF(("Plugin::LoadHelperNaClModule (%s)\n", | 685 PLUGIN_PRINTF(("Plugin::LoadHelperNaClModule (%s)\n", |
| 782 nacl_subprocess.get()->detailed_description().c_str())); | 686 nacl_subprocess.get()->detailed_description().c_str())); |
| 783 | 687 |
| 784 return nacl_subprocess.release(); | 688 return nacl_subprocess.release(); |
| 785 } | 689 } |
| 786 | 690 |
| 787 char* Plugin::LookupArgument(const char* key) { | 691 char* Plugin::LookupArgument(const char* key) { |
| 788 char** keys = argn(); | 692 char** keys = argn(); |
| 789 for (int ii = 0, len = argc(); ii < len; ++ii) { | 693 for (int ii = 0, len = argc(); ii < len; ++ii) { |
| 790 if (!strcmp(keys[ii], key)) { | 694 if (!strcmp(keys[ii], key)) { |
| 791 return argv()[ii]; | 695 return argv()[ii]; |
| 792 } | 696 } |
| 793 } | 697 } |
| 794 return NULL; | 698 return NULL; |
| 795 } | 699 } |
| 796 | 700 |
| 797 void Plugin::AddPropertyGet(RpcFunction function_ptr, | |
| 798 const char* name, | |
| 799 const char* outs) { | |
| 800 uintptr_t method_id = browser_interface()->StringToIdentifier(name); | |
| 801 PLUGIN_PRINTF(("Plugin::AddPropertyGet (name='%s', id=%" | |
| 802 NACL_PRIxPTR")\n", name, method_id)); | |
| 803 MethodInfo* new_method = new MethodInfo(function_ptr, name, "", outs); | |
| 804 property_get_methods_.AddMethod(method_id, new_method); | |
| 805 } | |
| 806 | |
| 807 MethodInfo* Plugin::GetMethodInfo(uintptr_t method_id, CallType call_type) { | |
| 808 MethodInfo* method_info = NULL; | |
| 809 switch (call_type) { | |
| 810 case PROPERTY_GET: | |
| 811 method_info = property_get_methods_.GetMethod(method_id); | |
| 812 break; | |
| 813 case PROPERTY_SET: | |
| 814 case METHOD_CALL: | |
| 815 break; | |
| 816 } | |
| 817 PLUGIN_PRINTF(("Plugin::GetMethodInfo (id=%"NACL_PRIxPTR", " | |
| 818 "return %p)\n", method_id, static_cast<void*>(method_info))); | |
| 819 return method_info; | |
| 820 } | |
| 821 | |
| 822 // Suggested names for progress event types, per | 701 // Suggested names for progress event types, per |
| 823 // http://www.w3.org/TR/progress-events/ | 702 // http://www.w3.org/TR/progress-events/ |
| 824 const char* const Plugin::kProgressEventLoadStart = "loadstart"; | 703 const char* const Plugin::kProgressEventLoadStart = "loadstart"; |
| 825 const char* const Plugin::kProgressEventProgress = "progress"; | 704 const char* const Plugin::kProgressEventProgress = "progress"; |
| 826 const char* const Plugin::kProgressEventError = "error"; | 705 const char* const Plugin::kProgressEventError = "error"; |
| 827 const char* const Plugin::kProgressEventAbort = "abort"; | 706 const char* const Plugin::kProgressEventAbort = "abort"; |
| 828 const char* const Plugin::kProgressEventLoad = "load"; | 707 const char* const Plugin::kProgressEventLoad = "load"; |
| 829 const char* const Plugin::kProgressEventLoadEnd = "loadend"; | 708 const char* const Plugin::kProgressEventLoadEnd = "loadend"; |
| 830 // Define a NaCl specific event type for .nexe crashes. | 709 // Define a NaCl specific event type for .nexe crashes. |
| 831 const char* const Plugin::kProgressEventCrash = "crash"; | 710 const char* const Plugin::kProgressEventCrash = "crash"; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 890 | 769 |
| 891 | 770 |
| 892 // All failures of this function will show up as "Missing Plugin-in", so | 771 // All failures of this function will show up as "Missing Plugin-in", so |
| 893 // there is no need to log to JS console that there was an initialization | 772 // there is no need to log to JS console that there was an initialization |
| 894 // failure. Note that module loading functions will log their own errors. | 773 // failure. Note that module loading functions will log their own errors. |
| 895 bool Plugin::Init(uint32_t argc, const char* argn[], const char* argv[]) { | 774 bool Plugin::Init(uint32_t argc, const char* argn[], const char* argv[]) { |
| 896 PLUGIN_PRINTF(("Plugin::Init (argc=%"NACL_PRIu32")\n", argc)); | 775 PLUGIN_PRINTF(("Plugin::Init (argc=%"NACL_PRIu32")\n", argc)); |
| 897 HistogramEnumerateOsArch(GetSandboxISA()); | 776 HistogramEnumerateOsArch(GetSandboxISA()); |
| 898 init_time_ = NaClGetTimeOfDayMicroseconds(); | 777 init_time_ = NaClGetTimeOfDayMicroseconds(); |
| 899 | 778 |
| 900 scoped_ptr<BrowserInterface> browser_interface( | 779 ScriptablePlugin* scriptable_plugin = ScriptablePlugin::NewPlugin(this); |
| 901 new(std::nothrow) BrowserInterface); | 780 if (scriptable_plugin == NULL) |
| 902 if (browser_interface == NULL) { | |
| 903 return false; | |
| 904 } | |
| 905 ScriptableHandle* handle = ScriptableHandle::NewPlugin(this); | |
| 906 if (handle == NULL) | |
| 907 return false; | 781 return false; |
| 908 | 782 |
| 909 set_scriptable_handle(handle); | 783 set_scriptable_plugin(scriptable_plugin); |
| 910 PLUGIN_PRINTF(("Plugin::Init (scriptable_handle=%p)\n", | 784 PLUGIN_PRINTF(("Plugin::Init (scriptable_handle=%p)\n", |
| 911 static_cast<void*>(scriptable_handle()))); | 785 static_cast<void*>(scriptable_plugin_))); |
| 912 url_util_ = pp::URLUtil_Dev::Get(); | 786 url_util_ = pp::URLUtil_Dev::Get(); |
| 913 if (url_util_ == NULL) | 787 if (url_util_ == NULL) |
| 914 return false; | 788 return false; |
| 915 | 789 |
| 916 PLUGIN_PRINTF(("Plugin::Init (url_util_=%p)\n", | 790 PLUGIN_PRINTF(("Plugin::Init (url_util_=%p)\n", |
| 917 static_cast<const void*>(url_util_))); | 791 static_cast<const void*>(url_util_))); |
| 918 | 792 |
| 919 bool status = Plugin::Init( | 793 bool status = Plugin::Init( |
| 920 browser_interface.release(), | |
| 921 static_cast<int>(argc), | 794 static_cast<int>(argc), |
| 922 // TODO(polina): Can we change the args on our end to be const to | 795 // TODO(polina): Can we change the args on our end to be const to |
| 923 // avoid these ugly casts? | 796 // avoid these ugly casts? |
| 924 const_cast<char**>(argn), | 797 const_cast<char**>(argn), |
| 925 const_cast<char**>(argv)); | 798 const_cast<char**>(argv)); |
| 926 if (status) { | 799 if (status) { |
| 927 // Look for the developer attribute; if it's present, enable 'dev' | 800 // Look for the developer attribute; if it's present, enable 'dev' |
| 928 // interfaces. | 801 // interfaces. |
| 929 const char* dev_settings = LookupArgument(kDevAttribute); | 802 const char* dev_settings = LookupArgument(kDevAttribute); |
| 930 enable_dev_interfaces_ = (dev_settings != NULL); | 803 enable_dev_interfaces_ = (dev_settings != NULL); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 965 " WARNING: 'nacl' property is incorrect. Use 'src'.\n")); | 838 " WARNING: 'nacl' property is incorrect. Use 'src'.\n")); |
| 966 } | 839 } |
| 967 } else { | 840 } else { |
| 968 // Issue a GET for the manifest_url. The manifest file will be parsed to | 841 // Issue a GET for the manifest_url. The manifest file will be parsed to |
| 969 // determine the nexe URL. | 842 // determine the nexe URL. |
| 970 // Sets src property to full manifest URL. | 843 // Sets src property to full manifest URL. |
| 971 RequestNaClManifest(manifest_url); | 844 RequestNaClManifest(manifest_url); |
| 972 } | 845 } |
| 973 } | 846 } |
| 974 | 847 |
| 975 // Export a property to allow us to get the last error description. | |
| 976 AddPropertyGet(GetLastError, "lastError", "s"); | |
| 977 // Export a property to allow us to get the nexe exit status. | |
| 978 AddPropertyGet(GetExitStatus, "exitStatus", "i"); | |
| 979 | |
| 980 PLUGIN_PRINTF(("Plugin::Init (status=%d)\n", status)); | 848 PLUGIN_PRINTF(("Plugin::Init (status=%d)\n", status)); |
| 981 return status; | 849 return status; |
| 982 } | 850 } |
| 983 | 851 |
| 984 | 852 |
| 985 Plugin::Plugin(PP_Instance pp_instance) | 853 Plugin::Plugin(PP_Instance pp_instance) |
| 986 : pp::InstancePrivate(pp_instance), | 854 : pp::InstancePrivate(pp_instance), |
| 987 browser_interface_(NULL), | 855 scriptable_plugin_(NULL), |
| 988 scriptable_handle_(NULL), | |
| 989 argc_(-1), | 856 argc_(-1), |
| 990 argn_(NULL), | 857 argn_(NULL), |
| 991 argv_(NULL), | 858 argv_(NULL), |
| 992 main_subprocess_("main subprocess", NULL, NULL, NULL), | 859 main_subprocess_("main subprocess", NULL, NULL), |
| 993 nacl_ready_state_(UNSENT), | 860 nacl_ready_state_(UNSENT), |
| 994 nexe_error_reported_(false), | 861 nexe_error_reported_(false), |
| 995 wrapper_factory_(NULL), | 862 wrapper_factory_(NULL), |
| 996 last_error_string_(""), | 863 last_error_string_(""), |
| 997 ppapi_proxy_(NULL), | 864 ppapi_proxy_(NULL), |
| 998 enable_dev_interfaces_(false), | 865 enable_dev_interfaces_(false), |
| 999 init_time_(0), | 866 init_time_(0), |
| 1000 ready_time_(0), | 867 ready_time_(0), |
| 1001 nexe_size_(0), | 868 nexe_size_(0), |
| 1002 time_of_last_progress_event_(0) { | 869 time_of_last_progress_event_(0) { |
| 1003 PLUGIN_PRINTF(("Plugin::Plugin (this=%p, pp_instance=%" | 870 PLUGIN_PRINTF(("Plugin::Plugin (this=%p, pp_instance=%" |
| 1004 NACL_PRId32")\n", static_cast<void*>(this), pp_instance)); | 871 NACL_PRId32")\n", static_cast<void*>(this), pp_instance)); |
| 1005 callback_factory_.Initialize(this); | 872 callback_factory_.Initialize(this); |
| 1006 nexe_downloader_.Initialize(this); | 873 nexe_downloader_.Initialize(this); |
| 1007 } | 874 } |
| 1008 | 875 |
| 1009 | 876 |
| 1010 Plugin::~Plugin() { | 877 Plugin::~Plugin() { |
| 1011 int64_t shutdown_start = NaClGetTimeOfDayMicroseconds(); | 878 int64_t shutdown_start = NaClGetTimeOfDayMicroseconds(); |
| 1012 | 879 |
| 1013 PLUGIN_PRINTF(("Plugin::~Plugin (this=%p, scriptable_handle=%p)\n", | 880 PLUGIN_PRINTF(("Plugin::~Plugin (this=%p, scriptable_plugin=%p)\n", |
| 1014 static_cast<void*>(this), | 881 static_cast<void*>(this), |
| 1015 static_cast<void*>(scriptable_handle()))); | 882 static_cast<void*>(scriptable_plugin()))); |
| 1016 | 883 |
| 1017 // If the proxy has been shutdown before now, it's likely the plugin suffered | 884 // If the proxy has been shutdown before now, it's likely the plugin suffered |
| 1018 // an error while loading. | 885 // an error while loading. |
| 1019 if (ppapi_proxy_ != NULL) { | 886 if (ppapi_proxy_ != NULL) { |
| 1020 HistogramTimeLarge( | 887 HistogramTimeLarge( |
| 1021 "NaCl.ModuleUptime.Normal", | 888 "NaCl.ModuleUptime.Normal", |
| 1022 (shutdown_start - ready_time_) / NACL_MICROS_PER_MILLI); | 889 (shutdown_start - ready_time_) / NACL_MICROS_PER_MILLI); |
| 1023 } | 890 } |
| 1024 | 891 |
| 1025 #if NACL_WINDOWS && !defined(NACL_STANDALONE) | 892 #if NACL_WINDOWS && !defined(NACL_STANDALONE) |
| 1026 NaClHandlePassBrowserDtor(); | 893 NaClHandlePassBrowserDtor(); |
| 1027 #endif | 894 #endif |
| 1028 | 895 |
| 1029 url_downloaders_.erase(url_downloaders_.begin(), url_downloaders_.end()); | 896 url_downloaders_.erase(url_downloaders_.begin(), url_downloaders_.end()); |
| 1030 | 897 |
| 1031 ShutdownProxy(); | 898 ShutdownProxy(); |
| 1032 ScriptableHandle* scriptable_handle_ = scriptable_handle(); | 899 ScriptablePlugin* scriptable_plugin_ = scriptable_plugin(); |
| 1033 ScriptableHandle::Unref(&scriptable_handle_); | 900 ScriptablePlugin::Unref(&scriptable_plugin_); |
| 1034 | 901 |
| 1035 // ShutDownSubprocesses shuts down the main subprocess, which shuts | 902 // ShutDownSubprocesses shuts down the main subprocess, which shuts |
| 1036 // down the main ServiceRuntime object, which kills the subprocess. | 903 // down the main ServiceRuntime object, which kills the subprocess. |
| 1037 // As a side effect of the subprocess being killed, the reverse | 904 // As a side effect of the subprocess being killed, the reverse |
| 1038 // services thread(s) will get EOF on the reverse channel(s), and | 905 // services thread(s) will get EOF on the reverse channel(s), and |
| 1039 // the thread(s) will exit. In ServiceRuntime::Shutdown, we invoke | 906 // the thread(s) will exit. In ServiceRuntime::Shutdown, we invoke |
| 1040 // ReverseService::WaitForServiceThreadsToExit(), so that there will | 907 // ReverseService::WaitForServiceThreadsToExit(), so that there will |
| 1041 // not be an extent thread(s) hanging around. This means that the | 908 // not be an extent thread(s) hanging around. This means that the |
| 1042 // ~Plugin will block until this happens. This is a requirement, | 909 // ~Plugin will block until this happens. This is a requirement, |
| 1043 // since the renderer should be free to unload the plugin code, and | 910 // since the renderer should be free to unload the plugin code, and |
| 1044 // we cannot have threads running code that gets unloaded before | 911 // we cannot have threads running code that gets unloaded before |
| 1045 // they exit. | 912 // they exit. |
| 1046 // | 913 // |
| 1047 // By waiting for the threads here, we also ensure that the Plugin | 914 // By waiting for the threads here, we also ensure that the Plugin |
| 1048 // object and the subprocess and ServiceRuntime objects is not | 915 // object and the subprocess and ServiceRuntime objects is not |
| 1049 // (fully) destroyed while the threads are running, so resources | 916 // (fully) destroyed while the threads are running, so resources |
| 1050 // that are destroyed after ShutDownSubprocesses (below) are | 917 // that are destroyed after ShutDownSubprocesses (below) are |
| 1051 // guaranteed to be live and valid for access from the service | 918 // guaranteed to be live and valid for access from the service |
| 1052 // threads. | 919 // threads. |
| 1053 // | 920 // |
| 1054 // The main_subprocess object, which wraps the main service_runtime | 921 // The main_subprocess object, which wraps the main service_runtime |
| 1055 // object, is dtor'd implicitly after the explicit code below runs, | 922 // object, is dtor'd implicitly after the explicit code below runs, |
| 1056 // so the main service runtime object will not have been dtor'd, | 923 // so the main service runtime object will not have been dtor'd, |
| 1057 // though the Shutdown method may have been called, during the | 924 // though the Shutdown method may have been called, during the |
| 1058 // lifetime of the service threads. | 925 // lifetime of the service threads. |
| 1059 ShutDownSubprocesses(); | 926 ShutDownSubprocesses(); |
| 1060 | 927 |
| 1061 delete wrapper_factory_; | 928 delete wrapper_factory_; |
| 1062 delete browser_interface_; | |
| 1063 delete[] argv_; | 929 delete[] argv_; |
| 1064 delete[] argn_; | 930 delete[] argn_; |
| 1065 | 931 |
| 1066 HistogramTimeSmall( | 932 HistogramTimeSmall( |
| 1067 "NaCl.Perf.ShutdownTime.Total", | 933 "NaCl.Perf.ShutdownTime.Total", |
| 1068 (NaClGetTimeOfDayMicroseconds() - shutdown_start) | 934 (NaClGetTimeOfDayMicroseconds() - shutdown_start) |
| 1069 / NACL_MICROS_PER_MILLI); | 935 / NACL_MICROS_PER_MILLI); |
| 1070 | 936 |
| 1071 PLUGIN_PRINTF(("Plugin::~Plugin (this=%p, return)\n", | 937 PLUGIN_PRINTF(("Plugin::~Plugin (this=%p, return)\n", |
| 1072 static_cast<void*>(this))); | 938 static_cast<void*>(this))); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1138 ppapi_proxy_->ppp_messaging_interface()->HandleMessage( | 1004 ppapi_proxy_->ppp_messaging_interface()->HandleMessage( |
| 1139 pp_instance(), message.pp_var()); | 1005 pp_instance(), message.pp_var()); |
| 1140 } | 1006 } |
| 1141 } | 1007 } |
| 1142 | 1008 |
| 1143 | 1009 |
| 1144 pp::Var Plugin::GetInstanceObject() { | 1010 pp::Var Plugin::GetInstanceObject() { |
| 1145 PLUGIN_PRINTF(("Plugin::GetInstanceObject (this=%p)\n", | 1011 PLUGIN_PRINTF(("Plugin::GetInstanceObject (this=%p)\n", |
| 1146 static_cast<void*>(this))); | 1012 static_cast<void*>(this))); |
| 1147 // The browser will unref when it discards the var for this object. | 1013 // The browser will unref when it discards the var for this object. |
| 1148 ScriptableHandle* handle = | 1014 ScriptablePlugin* handle = |
| 1149 static_cast<ScriptableHandle*>(scriptable_handle()->AddRef()); | 1015 static_cast<ScriptablePlugin*>(scriptable_plugin()->AddRef()); |
| 1150 pp::Var* handle_var = handle->var(); | 1016 pp::Var* handle_var = handle->var(); |
| 1151 PLUGIN_PRINTF(("Plugin::GetInstanceObject (handle=%p, handle_var=%p)\n", | 1017 PLUGIN_PRINTF(("Plugin::GetInstanceObject (handle=%p, handle_var=%p)\n", |
| 1152 static_cast<void*>(handle), static_cast<void*>(handle_var))); | 1018 static_cast<void*>(handle), static_cast<void*>(handle_var))); |
| 1153 return *handle_var; // make a copy | 1019 return *handle_var; // make a copy |
| 1154 } | 1020 } |
| 1155 | 1021 |
| 1156 void Plugin::HistogramStartupTimeSmall(const std::string& name, float dt) { | 1022 void Plugin::HistogramStartupTimeSmall(const std::string& name, float dt) { |
| 1157 if (nexe_size_ > 0) { | 1023 if (nexe_size_ > 0) { |
| 1158 float size_in_MB = static_cast<float>(nexe_size_) / (1024.f * 1024.f); | 1024 float size_in_MB = static_cast<float>(nexe_size_) / (1024.f * 1024.f); |
| 1159 HistogramTimeSmall(name, static_cast<int64_t>(dt)); | 1025 HistogramTimeSmall(name, static_cast<int64_t>(dt)); |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1434 if (nacl_ready_state() == DONE && !nexe_error_reported()) { // After loadEnd. | 1300 if (nacl_ready_state() == DONE && !nexe_error_reported()) { // After loadEnd. |
| 1435 int64_t crash_time = NaClGetTimeOfDayMicroseconds(); | 1301 int64_t crash_time = NaClGetTimeOfDayMicroseconds(); |
| 1436 // Crashes will be more likely near startup, so use a medium histogram | 1302 // Crashes will be more likely near startup, so use a medium histogram |
| 1437 // instead of a large one. | 1303 // instead of a large one. |
| 1438 HistogramTimeMedium( | 1304 HistogramTimeMedium( |
| 1439 "NaCl.ModuleUptime.Crash", | 1305 "NaCl.ModuleUptime.Crash", |
| 1440 (crash_time - ready_time_) / NACL_MICROS_PER_MILLI); | 1306 (crash_time - ready_time_) / NACL_MICROS_PER_MILLI); |
| 1441 | 1307 |
| 1442 nacl::string message = nacl::string("NaCl module crashed"); | 1308 nacl::string message = nacl::string("NaCl module crashed"); |
| 1443 set_last_error_string(message); | 1309 set_last_error_string(message); |
| 1444 browser_interface()->AddToConsole(this, message); | 1310 AddToConsole(message); |
| 1445 | 1311 |
| 1446 EnqueueProgressEvent(kProgressEventCrash); | 1312 EnqueueProgressEvent(kProgressEventCrash); |
| 1447 set_nexe_error_reported(true); | 1313 set_nexe_error_reported(true); |
| 1448 CHECK(ppapi_proxy_ == NULL || !ppapi_proxy_->is_valid()); | 1314 CHECK(ppapi_proxy_ == NULL || !ppapi_proxy_->is_valid()); |
| 1449 ShutdownProxy(); | 1315 ShutdownProxy(); |
| 1450 } | 1316 } |
| 1451 // else ReportLoadError() and ReportAbortError() will be used by loading code | 1317 // else ReportLoadError() and ReportAbortError() will be used by loading code |
| 1452 // to provide error handling and proxy shutdown. | 1318 // to provide error handling and proxy shutdown. |
| 1453 // | 1319 // |
| 1454 // NOTE: not all crashes during load will make it here. | 1320 // NOTE: not all crashes during load will make it here. |
| (...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1816 void Plugin::ReportLoadError(const ErrorInfo& error_info) { | 1682 void Plugin::ReportLoadError(const ErrorInfo& error_info) { |
| 1817 PLUGIN_PRINTF(("Plugin::ReportLoadError (error='%s')\n", | 1683 PLUGIN_PRINTF(("Plugin::ReportLoadError (error='%s')\n", |
| 1818 error_info.message().c_str())); | 1684 error_info.message().c_str())); |
| 1819 // Set the readyState attribute to indicate we need to start over. | 1685 // Set the readyState attribute to indicate we need to start over. |
| 1820 set_nacl_ready_state(DONE); | 1686 set_nacl_ready_state(DONE); |
| 1821 set_nexe_error_reported(true); | 1687 set_nexe_error_reported(true); |
| 1822 // Report an error in lastError and on the JavaScript console. | 1688 // Report an error in lastError and on the JavaScript console. |
| 1823 nacl::string message = nacl::string("NaCl module load failed: ") + | 1689 nacl::string message = nacl::string("NaCl module load failed: ") + |
| 1824 error_info.message(); | 1690 error_info.message(); |
| 1825 set_last_error_string(message); | 1691 set_last_error_string(message); |
| 1826 browser_interface()->AddToConsole(this, message); | 1692 AddToConsole(message); |
| 1827 ShutdownProxy(); | 1693 ShutdownProxy(); |
| 1828 // Inform JavaScript that loading encountered an error and is complete. | 1694 // Inform JavaScript that loading encountered an error and is complete. |
| 1829 EnqueueProgressEvent(kProgressEventError); | 1695 EnqueueProgressEvent(kProgressEventError); |
| 1830 EnqueueProgressEvent(kProgressEventLoadEnd); | 1696 EnqueueProgressEvent(kProgressEventLoadEnd); |
| 1831 | 1697 |
| 1832 // UMA | 1698 // UMA |
| 1833 HistogramEnumerateLoadStatus(error_info.error_code()); | 1699 HistogramEnumerateLoadStatus(error_info.error_code()); |
| 1834 } | 1700 } |
| 1835 | 1701 |
| 1836 | 1702 |
| 1837 void Plugin::ReportLoadAbort() { | 1703 void Plugin::ReportLoadAbort() { |
| 1838 PLUGIN_PRINTF(("Plugin::ReportLoadAbort\n")); | 1704 PLUGIN_PRINTF(("Plugin::ReportLoadAbort\n")); |
| 1839 // Set the readyState attribute to indicate we need to start over. | 1705 // Set the readyState attribute to indicate we need to start over. |
| 1840 set_nacl_ready_state(DONE); | 1706 set_nacl_ready_state(DONE); |
| 1841 set_nexe_error_reported(true); | 1707 set_nexe_error_reported(true); |
| 1842 // Report an error in lastError and on the JavaScript console. | 1708 // Report an error in lastError and on the JavaScript console. |
| 1843 nacl::string error_string("NaCl module load failed: user aborted"); | 1709 nacl::string error_string("NaCl module load failed: user aborted"); |
| 1844 set_last_error_string(error_string); | 1710 set_last_error_string(error_string); |
| 1845 browser_interface()->AddToConsole(this, error_string); | 1711 AddToConsole(error_string); |
| 1846 ShutdownProxy(); | 1712 ShutdownProxy(); |
| 1847 // Inform JavaScript that loading was aborted and is complete. | 1713 // Inform JavaScript that loading was aborted and is complete. |
| 1848 EnqueueProgressEvent(kProgressEventAbort); | 1714 EnqueueProgressEvent(kProgressEventAbort); |
| 1849 EnqueueProgressEvent(kProgressEventLoadEnd); | 1715 EnqueueProgressEvent(kProgressEventLoadEnd); |
| 1850 | 1716 |
| 1851 // UMA | 1717 // UMA |
| 1852 HistogramEnumerateLoadStatus(ERROR_LOAD_ABORTED); | 1718 HistogramEnumerateLoadStatus(ERROR_LOAD_ABORTED); |
| 1853 } | 1719 } |
| 1854 | 1720 |
| 1855 void Plugin::UpdateDownloadProgress( | 1721 void Plugin::UpdateDownloadProgress( |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2037 | 1903 |
| 2038 std::string scheme = canonicalized.AsString().substr(comps.scheme.begin, | 1904 std::string scheme = canonicalized.AsString().substr(comps.scheme.begin, |
| 2039 comps.scheme.len); | 1905 comps.scheme.len); |
| 2040 if (scheme == kChromeExtensionUriScheme) | 1906 if (scheme == kChromeExtensionUriScheme) |
| 2041 return SCHEME_CHROME_EXTENSION; | 1907 return SCHEME_CHROME_EXTENSION; |
| 2042 if (scheme == kDataUriScheme) | 1908 if (scheme == kDataUriScheme) |
| 2043 return SCHEME_DATA; | 1909 return SCHEME_DATA; |
| 2044 return SCHEME_OTHER; | 1910 return SCHEME_OTHER; |
| 2045 } | 1911 } |
| 2046 | 1912 |
| 1913 void Plugin::AddToConsole(const nacl::string& text) { | |
| 1914 pp::Module* module = pp::Module::Get(); | |
| 1915 const PPB_Var* var_interface = | |
| 1916 static_cast<const PPB_Var*>( | |
| 1917 module->GetBrowserInterface(PPB_VAR_INTERFACE)); | |
| 1918 nacl::string prefix_string("NativeClient"); | |
| 1919 PP_Var prefix = | |
| 1920 var_interface->VarFromUtf8(prefix_string.c_str(), | |
| 1921 static_cast<uint32_t>(prefix_string.size())); | |
| 1922 PP_Var str = var_interface->VarFromUtf8(text.c_str(), | |
| 1923 static_cast<uint32_t>(text.size())); | |
| 1924 const PPB_Console_Dev* console_interface = | |
| 1925 static_cast<const PPB_Console_Dev*>( | |
| 1926 module->GetBrowserInterface(PPB_CONSOLE_DEV_INTERFACE)); | |
| 1927 console_interface->LogWithSource(pp_instance(), PP_LOGLEVEL_LOG, prefix, str); | |
| 1928 var_interface->Release(prefix); | |
| 1929 var_interface->Release(str); | |
| 1930 } | |
| 1931 | |
| 2047 } // namespace plugin | 1932 } // namespace plugin |
| OLD | NEW |