Index: ppapi/native_client/src/shared/ppapi_proxy/browser_ppp.cc |
=================================================================== |
--- ppapi/native_client/src/shared/ppapi_proxy/browser_ppp.cc (revision 0) |
+++ ppapi/native_client/src/shared/ppapi_proxy/browser_ppp.cc (revision 0) |
@@ -0,0 +1,197 @@ |
+// Copyright (c) 2011 The Native Client Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "native_client/src/shared/ppapi_proxy/browser_ppp.h" |
+ |
+#include <string.h> |
+ |
+#include "native_client/src/include/nacl_scoped_ptr.h" |
+#include "native_client/src/include/portability.h" |
+#include "native_client/src/include/portability_process.h" |
+#include "native_client/src/shared/ppapi_proxy/browser_globals.h" |
+#include "native_client/src/shared/ppapi_proxy/browser_ppp_find.h" |
+#include "native_client/src/shared/ppapi_proxy/browser_ppp_input_event.h" |
+#include "native_client/src/shared/ppapi_proxy/browser_ppp_instance.h" |
+#include "native_client/src/shared/ppapi_proxy/browser_ppp_messaging.h" |
+#include "native_client/src/shared/ppapi_proxy/browser_ppp_printing.h" |
+#include "native_client/src/shared/ppapi_proxy/browser_ppp_scrollbar.h" |
+#include "native_client/src/shared/ppapi_proxy/browser_ppp_selection.h" |
+#include "native_client/src/shared/ppapi_proxy/browser_ppp_widget.h" |
+#include "native_client/src/shared/ppapi_proxy/browser_ppp_zoom.h" |
+#include "native_client/src/shared/ppapi_proxy/browser_upcall.h" |
+#include "native_client/src/shared/ppapi_proxy/trusted/srpcgen/ppb_rpc.h" |
+#include "native_client/src/shared/ppapi_proxy/trusted/srpcgen/ppp_rpc.h" |
+#include "native_client/src/shared/ppapi_proxy/utility.h" |
+#include "native_client/src/trusted/desc/nacl_desc_wrapper.h" |
+#include "native_client/src/trusted/plugin/plugin.h" |
+#include "ppapi/c/ppp_input_event.h" |
+#include "ppapi/c/dev/ppp_find_dev.h" |
+#include "ppapi/c/dev/ppp_printing_dev.h" |
+#include "ppapi/c/dev/ppp_scrollbar_dev.h" |
+#include "ppapi/c/dev/ppp_selection_dev.h" |
+#include "ppapi/c/dev/ppp_widget_dev.h" |
+#include "ppapi/c/dev/ppp_zoom_dev.h" |
+#include "ppapi/c/pp_errors.h" |
+#include "ppapi/c/ppp.h" |
+ |
+namespace ppapi_proxy { |
+ |
+// |
+// The following methods are the SRPC dispatchers for ppapi/c/ppp.h. |
+// |
+ |
+namespace { |
+ |
+// PPB_GetInterface must only be called on the main thread. So as we are adding |
+// off-the-main-thread support for various interfaces, we need to ensure that |
+// their pointers are available on upcall thread of the the trusted proxy. |
+void PPBGetInterfaces() { |
+ PPBCoreInterface(); |
+ // TODO(all): add more interfaces here once available off the main thread. |
+} |
+ |
+} // namespace |
+ |
+int32_t BrowserPpp::InitializeModule(PP_Module module_id, |
+ PPB_GetInterface get_browser_interface) { |
+ DebugPrintf("PPP_InitializeModule: module=%"NACL_PRIu32"\n", module_id); |
+ SetPPBGetInterface(get_browser_interface, plugin_->enable_dev_interface()); |
+ PPBGetInterfaces(); |
+ |
+ SetBrowserPppForInstance(plugin_->pp_instance(), this); |
+ CHECK(main_channel_ != NULL); |
+ nacl::scoped_ptr<nacl::DescWrapper> wrapper( |
+ BrowserUpcall::Start(&upcall_thread_, main_channel_)); |
+ if (wrapper.get() == NULL) |
+ return PP_ERROR_FAILED; |
+ // Set up the callbacks allowed on the main channel. |
+ NaClSrpcService* service = reinterpret_cast<NaClSrpcService*>( |
+ calloc(1, sizeof(*service))); |
+ if (NULL == service) { |
+ DebugPrintf("PPP_InitializeModule: " |
+ "could not create callback services.\n"); |
+ return PP_ERROR_FAILED; |
+ } |
+ if (!NaClSrpcServiceHandlerCtor(service, PpbRpcs::srpc_methods)) { |
+ DebugPrintf("PPP_InitializeModule: " |
+ "could not construct callback services.\n"); |
+ free(service); |
+ return PP_ERROR_FAILED; |
+ } |
+ // Export the service on the channel. |
+ main_channel_->server = service; |
+ char* service_string = const_cast<char*>(service->service_string); |
+ SetModuleIdForSrpcChannel(main_channel_, module_id); |
+ SetInstanceIdForSrpcChannel(main_channel_, plugin_->pp_instance()); |
+ // Do the RPC. |
+ int32_t browser_pid = static_cast<int32_t>(GETPID()); |
+ int32_t pp_error; |
+ NaClSrpcError srpc_result = |
+ PppRpcClient::PPP_InitializeModule(main_channel_, |
+ browser_pid, |
+ module_id, |
+ wrapper->desc(), |
+ service_string, |
+ &plugin_pid_, |
+ &pp_error); |
+ DebugPrintf("PPP_InitializeModule: %s\n", NaClSrpcErrorString(srpc_result)); |
+ is_nexe_alive_ = (srpc_result != NACL_SRPC_RESULT_INTERNAL); |
+ if (srpc_result != NACL_SRPC_RESULT_OK) |
+ return PP_ERROR_FAILED; |
+ DebugPrintf("PPP_InitializeModule: pp_error=%"NACL_PRId32"\n", pp_error); |
+ if (pp_error != PP_OK) |
+ return pp_error; |
+ const void* ppp_instance = GetPluginInterface(PPP_INSTANCE_INTERFACE); |
+ DebugPrintf("PPP_InitializeModule: ppp_instance=%p\n", ppp_instance); |
+ ppp_instance_interface_ = reinterpret_cast<const PPP_Instance*>(ppp_instance); |
+ if (ppp_instance_interface_ == NULL) // PPP_Instance is required. |
+ return PP_ERROR_NOINTERFACE; |
+ // PPB_Messaging and PPP_InputEvent are optional, so it's OK for them to |
+ // return NULL. |
+ ppp_messaging_interface_ = reinterpret_cast<const PPP_Messaging*>( |
+ GetPluginInterface(PPP_MESSAGING_INTERFACE)); |
+ ppp_input_event_interface_ = reinterpret_cast<const PPP_InputEvent*>( |
+ GetPluginInterface(PPP_INPUT_EVENT_INTERFACE)); |
+ if (!is_valid()) // Nexe died in PPP_GetInterface. |
+ return PP_ERROR_FAILED; |
+ return PP_OK; |
+} |
+ |
+void BrowserPpp::ShutdownModule() { |
+ DebugPrintf("PPP_Shutdown: main_channel=%p\n", |
+ static_cast<void*>(main_channel_)); |
+ if (main_channel_ == NULL) { |
+ CHECK(!is_nexe_alive_); |
+ return; // The proxy has already been shut down. |
+ } |
+ NaClSrpcError srpc_result = |
+ PppRpcClient::PPP_ShutdownModule(main_channel_); |
+ DebugPrintf("PPP_ShutdownModule: %s\n", NaClSrpcErrorString(srpc_result)); |
+ NaClThreadJoin(&upcall_thread_); |
+ UnsetBrowserPppForInstance(plugin_->pp_instance()); |
+ UnsetModuleIdForSrpcChannel(main_channel_); |
+ UnsetInstanceIdForSrpcChannel(main_channel_); |
+ main_channel_ = NULL; |
+ is_nexe_alive_ = false; |
+ DebugPrintf("PPP_Shutdown: done\n"); |
+} |
+ |
+const void* BrowserPpp::GetPluginInterface(const char* interface_name) { |
+ DebugPrintf("PPP_GetInterface('%s')\n", interface_name); |
+ if (!is_valid()) |
+ return NULL; |
+ int32_t exports_interface_name; |
+ NaClSrpcError srpc_result = |
+ PppRpcClient::PPP_GetInterface(main_channel_, |
+ const_cast<char*>(interface_name), |
+ &exports_interface_name); |
+ DebugPrintf("PPP_GetInterface('%s'): %s\n", |
+ interface_name, NaClSrpcErrorString(srpc_result)); |
+ is_nexe_alive_ = (srpc_result != NACL_SRPC_RESULT_INTERNAL); |
+ |
+ const void* ppp_interface = NULL; |
+ if (srpc_result != NACL_SRPC_RESULT_OK || !exports_interface_name) { |
+ ppp_interface = NULL; |
+ } else if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0) { |
+ ppp_interface = |
+ reinterpret_cast<const void*>(BrowserInstance::GetInterface()); |
+ } else if (strcmp(interface_name, PPP_MESSAGING_INTERFACE) == 0) { |
+ ppp_interface = |
+ reinterpret_cast<const void*>(BrowserMessaging::GetInterface()); |
+ } else if (strcmp(interface_name, PPP_INPUT_EVENT_INTERFACE) == 0) { |
+ ppp_interface = |
+ reinterpret_cast<const void*>(BrowserInputEvent::GetInterface()); |
+ } else if (strcmp(interface_name, PPP_FIND_DEV_INTERFACE) == 0) { |
+ ppp_interface = |
+ reinterpret_cast<const void*>(BrowserFind::GetInterface()); |
+ } else if (strcmp(interface_name, PPP_PRINTING_DEV_INTERFACE) == 0) { |
+ ppp_interface = |
+ reinterpret_cast<const void*>(BrowserPrinting::GetInterface()); |
+ } else if (strcmp(interface_name, PPP_SCROLLBAR_DEV_INTERFACE) == 0) { |
+ ppp_interface = |
+ reinterpret_cast<const void*>(BrowserScrollbar::GetInterface()); |
+ } else if (strcmp(interface_name, PPP_SELECTION_DEV_INTERFACE) == 0) { |
+ ppp_interface = |
+ reinterpret_cast<const void*>(BrowserSelection::GetInterface()); |
+ } else if (strcmp(interface_name, PPP_WIDGET_DEV_INTERFACE) == 0) { |
+ ppp_interface = |
+ reinterpret_cast<const void*>(BrowserWidget::GetInterface()); |
+ } else if (strcmp(interface_name, PPP_ZOOM_DEV_INTERFACE) == 0) { |
+ ppp_interface = |
+ reinterpret_cast<const void*>(BrowserZoom::GetInterface()); |
+ } |
+ // TODO(sehr): other interfaces go here. |
+ DebugPrintf("PPP_GetInterface('%s'): %p\n", interface_name, ppp_interface); |
+ return ppp_interface; |
+} |
+ |
+const void* BrowserPpp::GetPluginInterfaceSafe(const char* interface_name) { |
+ const void* ppp_interface = GetPluginInterface(interface_name); |
+ if (ppp_interface == NULL) |
+ DebugPrintf("PPB_GetInterface: %s not found\n", interface_name); |
+ CHECK(ppp_interface != NULL); |
+ return ppp_interface; |
+} |
+ |
+} // namespace ppapi_proxy |