| OLD | NEW |
| (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 | |
| 8 #include <string.h> | |
| 9 | |
| 10 #include <map> | |
| 11 | |
| 12 #include "native_client/src/shared/platform/nacl_log.h" | |
| 13 #include "native_client/src/trusted/plugin/browser_interface.h" | |
| 14 #include "native_client/src/trusted/plugin/desc_based_handle.h" | |
| 15 #include "native_client/src/trusted/plugin/plugin.h" | |
| 16 #include "native_client/src/trusted/plugin/scriptable_handle.h" | |
| 17 #include "native_client/src/trusted/plugin/srpc_client.h" | |
| 18 #include "native_client/src/trusted/plugin/utility.h" | |
| 19 | |
| 20 namespace plugin { | |
| 21 | |
| 22 SrpcClient::SrpcClient() | |
| 23 : srpc_channel_initialised_(false), | |
| 24 browser_interface_(NULL) { | |
| 25 PLUGIN_PRINTF(("SrpcClient::SrpcClient (this=%p)\n", | |
| 26 static_cast<void*>(this))); | |
| 27 NaClSrpcChannelInitialize(&srpc_channel_); | |
| 28 } | |
| 29 | |
| 30 SrpcClient* SrpcClient::New(Plugin* plugin, nacl::DescWrapper* wrapper) { | |
| 31 nacl::scoped_ptr<SrpcClient> srpc_client(new SrpcClient()); | |
| 32 if (!srpc_client->Init(plugin->browser_interface(), wrapper)) { | |
| 33 PLUGIN_PRINTF(("SrpcClient::New (SrpcClient::Init failed)\n")); | |
| 34 return NULL; | |
| 35 } | |
| 36 return srpc_client.release(); | |
| 37 } | |
| 38 | |
| 39 bool SrpcClient::Init(BrowserInterface* browser_interface, | |
| 40 nacl::DescWrapper* wrapper) { | |
| 41 PLUGIN_PRINTF(("SrpcClient::Init (this=%p, browser_interface=%p, wrapper=%p)" | |
| 42 "\n", static_cast<void*>(this), | |
| 43 static_cast<void*>(browser_interface), | |
| 44 static_cast<void*>(wrapper))); | |
| 45 // Open the channel to pass RPC information back and forth | |
| 46 if (!NaClSrpcClientCtor(&srpc_channel_, wrapper->desc())) { | |
| 47 return false; | |
| 48 } | |
| 49 srpc_channel_initialised_ = true; | |
| 50 browser_interface_ = browser_interface; | |
| 51 PLUGIN_PRINTF(("SrpcClient::Init (Ctor worked)\n")); | |
| 52 // Record the method names in a convenient way for later dispatches. | |
| 53 GetMethods(); | |
| 54 PLUGIN_PRINTF(("SrpcClient::Init (GetMethods worked)\n")); | |
| 55 return true; | |
| 56 } | |
| 57 | |
| 58 SrpcClient::~SrpcClient() { | |
| 59 PLUGIN_PRINTF(("SrpcClient::~SrpcClient (this=%p, has_srpc_channel=%d)\n", | |
| 60 static_cast<void*>(this), srpc_channel_initialised_)); | |
| 61 // And delete the connection. | |
| 62 if (srpc_channel_initialised_) { | |
| 63 PLUGIN_PRINTF(("SrpcClient::~SrpcClient (destroying srpc_channel)\n")); | |
| 64 NaClSrpcDtor(&srpc_channel_); | |
| 65 } | |
| 66 for (Methods::iterator iter = methods_.begin(); | |
| 67 iter != methods_.end(); | |
| 68 ++iter) { | |
| 69 delete iter->second; | |
| 70 } | |
| 71 PLUGIN_PRINTF(("SrpcClient::~SrpcClient (return)\n")); | |
| 72 } | |
| 73 | |
| 74 bool SrpcClient::StartJSObjectProxy(Plugin* plugin, | |
| 75 ErrorInfo *error_info) { | |
| 76 // Start up PPAPI interaction if the plugin determines that the | |
| 77 // requisite methods are exported. | |
| 78 return plugin->StartProxiedExecution(&srpc_channel_, error_info); | |
| 79 } | |
| 80 | |
| 81 void SrpcClient::GetMethods() { | |
| 82 PLUGIN_PRINTF(("SrpcClient::GetMethods (this=%p)\n", | |
| 83 static_cast<void*>(this))); | |
| 84 if (NULL == srpc_channel_.client) { | |
| 85 return; | |
| 86 } | |
| 87 uint32_t method_count = NaClSrpcServiceMethodCount(srpc_channel_.client); | |
| 88 // Intern the methods into a mapping from identifiers to MethodInfo. | |
| 89 for (uint32_t i = 0; i < method_count; ++i) { | |
| 90 int retval; | |
| 91 const char* name; | |
| 92 const char* input_types; | |
| 93 const char* output_types; | |
| 94 | |
| 95 retval = NaClSrpcServiceMethodNameAndTypes(srpc_channel_.client, | |
| 96 i, | |
| 97 &name, | |
| 98 &input_types, | |
| 99 &output_types); | |
| 100 if (!IsValidIdentifierString(name, NULL)) { | |
| 101 // If name is not an ECMAScript identifier, do not enter it into the | |
| 102 // methods_ table. | |
| 103 continue; | |
| 104 } | |
| 105 uintptr_t ident = browser_interface_->StringToIdentifier(name); | |
| 106 MethodInfo* method_info = | |
| 107 new MethodInfo(NULL, name, input_types, output_types, i); | |
| 108 if (NULL == method_info) { | |
| 109 return; | |
| 110 } | |
| 111 // Install in the map only if successfully read. | |
| 112 methods_[ident] = method_info; | |
| 113 } | |
| 114 } | |
| 115 | |
| 116 bool SrpcClient::HasMethod(uintptr_t method_id) { | |
| 117 bool has_method = (NULL != methods_[method_id]); | |
| 118 PLUGIN_PRINTF(("SrpcClient::HasMethod (this=%p, return %d)\n", | |
| 119 static_cast<void*>(this), has_method)); | |
| 120 return has_method; | |
| 121 } | |
| 122 | |
| 123 bool SrpcClient::InitParams(uintptr_t method_id, SrpcParams* params) { | |
| 124 MethodInfo* method_info = methods_[method_id]; | |
| 125 if (method_info) { | |
| 126 return params->Init(method_info->ins(), method_info->outs()); | |
| 127 } | |
| 128 return false; | |
| 129 } | |
| 130 | |
| 131 bool SrpcClient::Invoke(uintptr_t method_id, | |
| 132 SrpcParams* params) { | |
| 133 // It would be better if we could set the exception on each detailed failure | |
| 134 // case. However, there are calls to Invoke from within the plugin itself, | |
| 135 // and these could leave residual exceptions pending. This seems to be | |
| 136 // happening specifically with hard_shutdowns. | |
| 137 PLUGIN_PRINTF(("SrpcClient::Invoke (this=%p, method_name='%s', params=%p)\n", | |
| 138 static_cast<void*>(this), | |
| 139 browser_interface_->IdentifierToString(method_id).c_str(), | |
| 140 static_cast<void*>(params))); | |
| 141 | |
| 142 // Ensure Invoke was called with an identifier that had a binding. | |
| 143 if (NULL == methods_[method_id]) { | |
| 144 PLUGIN_PRINTF(("SrpcClient::Invoke (ident not in methods_)\n")); | |
| 145 return false; | |
| 146 } | |
| 147 | |
| 148 PLUGIN_PRINTF(("SrpcClient::Invoke (sending the rpc)\n")); | |
| 149 // Call the method | |
| 150 NaClSrpcError err = NaClSrpcInvokeV(&srpc_channel_, | |
| 151 methods_[method_id]->index(), | |
| 152 params->ins(), | |
| 153 params->outs()); | |
| 154 PLUGIN_PRINTF(("SrpcClient::Invoke (response=%d)\n", err)); | |
| 155 if (NACL_SRPC_RESULT_OK != err) { | |
| 156 PLUGIN_PRINTF(("SrpcClient::Invoke (err='%s', return 0)\n", | |
| 157 NaClSrpcErrorString(err))); | |
| 158 return false; | |
| 159 } | |
| 160 | |
| 161 PLUGIN_PRINTF(("SrpcClient::Invoke (return 1)\n")); | |
| 162 return true; | |
| 163 } | |
| 164 | |
| 165 } // namespace plugin | |
| OLD | NEW |