OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011 The Native Client Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "native_client/src/shared/ppapi_proxy/browser_ppp.h" |
| 6 |
| 7 #include <string.h> |
| 8 |
| 9 #include "native_client/src/include/nacl_scoped_ptr.h" |
| 10 #include "native_client/src/include/portability.h" |
| 11 #include "native_client/src/include/portability_process.h" |
| 12 #include "native_client/src/shared/ppapi_proxy/browser_globals.h" |
| 13 #include "native_client/src/shared/ppapi_proxy/browser_ppp_find.h" |
| 14 #include "native_client/src/shared/ppapi_proxy/browser_ppp_input_event.h" |
| 15 #include "native_client/src/shared/ppapi_proxy/browser_ppp_instance.h" |
| 16 #include "native_client/src/shared/ppapi_proxy/browser_ppp_messaging.h" |
| 17 #include "native_client/src/shared/ppapi_proxy/browser_ppp_printing.h" |
| 18 #include "native_client/src/shared/ppapi_proxy/browser_ppp_scrollbar.h" |
| 19 #include "native_client/src/shared/ppapi_proxy/browser_ppp_selection.h" |
| 20 #include "native_client/src/shared/ppapi_proxy/browser_ppp_widget.h" |
| 21 #include "native_client/src/shared/ppapi_proxy/browser_ppp_zoom.h" |
| 22 #include "native_client/src/shared/ppapi_proxy/browser_upcall.h" |
| 23 #include "native_client/src/shared/ppapi_proxy/trusted/srpcgen/ppb_rpc.h" |
| 24 #include "native_client/src/shared/ppapi_proxy/trusted/srpcgen/ppp_rpc.h" |
| 25 #include "native_client/src/shared/ppapi_proxy/utility.h" |
| 26 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" |
| 27 #include "native_client/src/trusted/plugin/plugin.h" |
| 28 #include "ppapi/c/ppp_input_event.h" |
| 29 #include "ppapi/c/dev/ppp_find_dev.h" |
| 30 #include "ppapi/c/dev/ppp_printing_dev.h" |
| 31 #include "ppapi/c/dev/ppp_scrollbar_dev.h" |
| 32 #include "ppapi/c/dev/ppp_selection_dev.h" |
| 33 #include "ppapi/c/dev/ppp_widget_dev.h" |
| 34 #include "ppapi/c/dev/ppp_zoom_dev.h" |
| 35 #include "ppapi/c/pp_errors.h" |
| 36 #include "ppapi/c/ppp.h" |
| 37 |
| 38 namespace ppapi_proxy { |
| 39 |
| 40 // |
| 41 // The following methods are the SRPC dispatchers for ppapi/c/ppp.h. |
| 42 // |
| 43 |
| 44 namespace { |
| 45 |
| 46 // PPB_GetInterface must only be called on the main thread. So as we are adding |
| 47 // off-the-main-thread support for various interfaces, we need to ensure that |
| 48 // their pointers are available on upcall thread of the the trusted proxy. |
| 49 void PPBGetInterfaces() { |
| 50 PPBCoreInterface(); |
| 51 // TODO(all): add more interfaces here once available off the main thread. |
| 52 } |
| 53 |
| 54 } // namespace |
| 55 |
| 56 int32_t BrowserPpp::InitializeModule(PP_Module module_id, |
| 57 PPB_GetInterface get_browser_interface) { |
| 58 DebugPrintf("PPP_InitializeModule: module=%"NACL_PRIu32"\n", module_id); |
| 59 SetPPBGetInterface(get_browser_interface, plugin_->enable_dev_interface()); |
| 60 PPBGetInterfaces(); |
| 61 |
| 62 SetBrowserPppForInstance(plugin_->pp_instance(), this); |
| 63 CHECK(main_channel_ != NULL); |
| 64 nacl::scoped_ptr<nacl::DescWrapper> wrapper( |
| 65 BrowserUpcall::Start(&upcall_thread_, main_channel_)); |
| 66 if (wrapper.get() == NULL) |
| 67 return PP_ERROR_FAILED; |
| 68 // Set up the callbacks allowed on the main channel. |
| 69 NaClSrpcService* service = reinterpret_cast<NaClSrpcService*>( |
| 70 calloc(1, sizeof(*service))); |
| 71 if (NULL == service) { |
| 72 DebugPrintf("PPP_InitializeModule: " |
| 73 "could not create callback services.\n"); |
| 74 return PP_ERROR_FAILED; |
| 75 } |
| 76 if (!NaClSrpcServiceHandlerCtor(service, PpbRpcs::srpc_methods)) { |
| 77 DebugPrintf("PPP_InitializeModule: " |
| 78 "could not construct callback services.\n"); |
| 79 free(service); |
| 80 return PP_ERROR_FAILED; |
| 81 } |
| 82 // Export the service on the channel. |
| 83 main_channel_->server = service; |
| 84 char* service_string = const_cast<char*>(service->service_string); |
| 85 SetModuleIdForSrpcChannel(main_channel_, module_id); |
| 86 SetInstanceIdForSrpcChannel(main_channel_, plugin_->pp_instance()); |
| 87 // Do the RPC. |
| 88 int32_t browser_pid = static_cast<int32_t>(GETPID()); |
| 89 int32_t pp_error; |
| 90 NaClSrpcError srpc_result = |
| 91 PppRpcClient::PPP_InitializeModule(main_channel_, |
| 92 browser_pid, |
| 93 module_id, |
| 94 wrapper->desc(), |
| 95 service_string, |
| 96 &plugin_pid_, |
| 97 &pp_error); |
| 98 DebugPrintf("PPP_InitializeModule: %s\n", NaClSrpcErrorString(srpc_result)); |
| 99 is_nexe_alive_ = (srpc_result != NACL_SRPC_RESULT_INTERNAL); |
| 100 if (srpc_result != NACL_SRPC_RESULT_OK) |
| 101 return PP_ERROR_FAILED; |
| 102 DebugPrintf("PPP_InitializeModule: pp_error=%"NACL_PRId32"\n", pp_error); |
| 103 if (pp_error != PP_OK) |
| 104 return pp_error; |
| 105 const void* ppp_instance = GetPluginInterface(PPP_INSTANCE_INTERFACE); |
| 106 DebugPrintf("PPP_InitializeModule: ppp_instance=%p\n", ppp_instance); |
| 107 ppp_instance_interface_ = reinterpret_cast<const PPP_Instance*>(ppp_instance); |
| 108 if (ppp_instance_interface_ == NULL) // PPP_Instance is required. |
| 109 return PP_ERROR_NOINTERFACE; |
| 110 // PPB_Messaging and PPP_InputEvent are optional, so it's OK for them to |
| 111 // return NULL. |
| 112 ppp_messaging_interface_ = reinterpret_cast<const PPP_Messaging*>( |
| 113 GetPluginInterface(PPP_MESSAGING_INTERFACE)); |
| 114 ppp_input_event_interface_ = reinterpret_cast<const PPP_InputEvent*>( |
| 115 GetPluginInterface(PPP_INPUT_EVENT_INTERFACE)); |
| 116 if (!is_valid()) // Nexe died in PPP_GetInterface. |
| 117 return PP_ERROR_FAILED; |
| 118 return PP_OK; |
| 119 } |
| 120 |
| 121 void BrowserPpp::ShutdownModule() { |
| 122 DebugPrintf("PPP_Shutdown: main_channel=%p\n", |
| 123 static_cast<void*>(main_channel_)); |
| 124 if (main_channel_ == NULL) { |
| 125 CHECK(!is_nexe_alive_); |
| 126 return; // The proxy has already been shut down. |
| 127 } |
| 128 NaClSrpcError srpc_result = |
| 129 PppRpcClient::PPP_ShutdownModule(main_channel_); |
| 130 DebugPrintf("PPP_ShutdownModule: %s\n", NaClSrpcErrorString(srpc_result)); |
| 131 NaClThreadJoin(&upcall_thread_); |
| 132 UnsetBrowserPppForInstance(plugin_->pp_instance()); |
| 133 UnsetModuleIdForSrpcChannel(main_channel_); |
| 134 UnsetInstanceIdForSrpcChannel(main_channel_); |
| 135 main_channel_ = NULL; |
| 136 is_nexe_alive_ = false; |
| 137 DebugPrintf("PPP_Shutdown: done\n"); |
| 138 } |
| 139 |
| 140 const void* BrowserPpp::GetPluginInterface(const char* interface_name) { |
| 141 DebugPrintf("PPP_GetInterface('%s')\n", interface_name); |
| 142 if (!is_valid()) |
| 143 return NULL; |
| 144 int32_t exports_interface_name; |
| 145 NaClSrpcError srpc_result = |
| 146 PppRpcClient::PPP_GetInterface(main_channel_, |
| 147 const_cast<char*>(interface_name), |
| 148 &exports_interface_name); |
| 149 DebugPrintf("PPP_GetInterface('%s'): %s\n", |
| 150 interface_name, NaClSrpcErrorString(srpc_result)); |
| 151 is_nexe_alive_ = (srpc_result != NACL_SRPC_RESULT_INTERNAL); |
| 152 |
| 153 const void* ppp_interface = NULL; |
| 154 if (srpc_result != NACL_SRPC_RESULT_OK || !exports_interface_name) { |
| 155 ppp_interface = NULL; |
| 156 } else if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0) { |
| 157 ppp_interface = |
| 158 reinterpret_cast<const void*>(BrowserInstance::GetInterface()); |
| 159 } else if (strcmp(interface_name, PPP_MESSAGING_INTERFACE) == 0) { |
| 160 ppp_interface = |
| 161 reinterpret_cast<const void*>(BrowserMessaging::GetInterface()); |
| 162 } else if (strcmp(interface_name, PPP_INPUT_EVENT_INTERFACE) == 0) { |
| 163 ppp_interface = |
| 164 reinterpret_cast<const void*>(BrowserInputEvent::GetInterface()); |
| 165 } else if (strcmp(interface_name, PPP_FIND_DEV_INTERFACE) == 0) { |
| 166 ppp_interface = |
| 167 reinterpret_cast<const void*>(BrowserFind::GetInterface()); |
| 168 } else if (strcmp(interface_name, PPP_PRINTING_DEV_INTERFACE) == 0) { |
| 169 ppp_interface = |
| 170 reinterpret_cast<const void*>(BrowserPrinting::GetInterface()); |
| 171 } else if (strcmp(interface_name, PPP_SCROLLBAR_DEV_INTERFACE) == 0) { |
| 172 ppp_interface = |
| 173 reinterpret_cast<const void*>(BrowserScrollbar::GetInterface()); |
| 174 } else if (strcmp(interface_name, PPP_SELECTION_DEV_INTERFACE) == 0) { |
| 175 ppp_interface = |
| 176 reinterpret_cast<const void*>(BrowserSelection::GetInterface()); |
| 177 } else if (strcmp(interface_name, PPP_WIDGET_DEV_INTERFACE) == 0) { |
| 178 ppp_interface = |
| 179 reinterpret_cast<const void*>(BrowserWidget::GetInterface()); |
| 180 } else if (strcmp(interface_name, PPP_ZOOM_DEV_INTERFACE) == 0) { |
| 181 ppp_interface = |
| 182 reinterpret_cast<const void*>(BrowserZoom::GetInterface()); |
| 183 } |
| 184 // TODO(sehr): other interfaces go here. |
| 185 DebugPrintf("PPP_GetInterface('%s'): %p\n", interface_name, ppp_interface); |
| 186 return ppp_interface; |
| 187 } |
| 188 |
| 189 const void* BrowserPpp::GetPluginInterfaceSafe(const char* interface_name) { |
| 190 const void* ppp_interface = GetPluginInterface(interface_name); |
| 191 if (ppp_interface == NULL) |
| 192 DebugPrintf("PPB_GetInterface: %s not found\n", interface_name); |
| 193 CHECK(ppp_interface != NULL); |
| 194 return ppp_interface; |
| 195 } |
| 196 |
| 197 } // namespace ppapi_proxy |
OLD | NEW |