| // Copyright (c) 2012 The Chromium 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_globals.h" |
| |
| #include <stddef.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| |
| #include <map> |
| |
| #include "native_client/src/include/nacl_macros.h" |
| #include "native_client/src/shared/platform/nacl_check.h" |
| #include "native_client/src/shared/ppapi_proxy/browser_ppp.h" |
| #include "native_client/src/shared/ppapi_proxy/utility.h" |
| #include "native_client/src/shared/srpc/nacl_srpc.h" |
| #include "native_client/src/trusted/plugin/plugin.h" |
| #include "ppapi/c/dev/ppb_gles_chromium_texture_mapping_dev.h" |
| #include "ppapi/c/dev/ppb_layer_compositor_dev.h" |
| #include "ppapi/c/dev/ppb_opengles2ext_dev.h" |
| #include "ppapi/c/ppb_graphics_3d.h" |
| #include "ppapi/c/ppb_opengles2.h" |
| #include "ppapi/c/trusted/ppb_graphics_3d_trusted.h" |
| |
| namespace ppapi_proxy { |
| |
| // All of these methods are called from the browser main (UI, JavaScript, ...) |
| // thread. |
| |
| const PP_Resource kInvalidResourceId = 0; |
| |
| namespace { |
| |
| std::map<PP_Instance, BrowserPpp*>* instance_to_ppp_map = NULL; |
| |
| // In the future, we might have one sel_ldr with one channel per module, shared |
| // by multiple instances, where each instance consists of a trusted plugin with |
| // a proxy to a nexe. When this happens, we will need to provide the instance id |
| // with each SRPC message. But in the meantime it is enough to map channels |
| // to instances since each proxy has its own SRPC channel. |
| std::map<NaClSrpcChannel*, PP_Module>* channel_to_module_id_map = NULL; |
| std::map<NaClSrpcChannel*, PP_Instance>* channel_to_instance_id_map = NULL; |
| |
| // The function pointer from the browser, and whether or not the plugin |
| // is requesting PPAPI Dev interfaces to be available. |
| // Set by SetPPBGetInterface(). |
| PPB_GetInterface get_interface = NULL; |
| bool enable_dev_interfaces = false; |
| |
| // Whether Pepper 3D interfaces should be enabled. |
| bool enable_3d_interfaces = true; |
| |
| } // namespace |
| |
| void SetBrowserPppForInstance(PP_Instance instance, BrowserPpp* browser_ppp) { |
| // If there was no map, create one. |
| if (NULL == instance_to_ppp_map) { |
| instance_to_ppp_map = new std::map<PP_Instance, BrowserPpp*>; |
| } |
| // Add the instance to the map. |
| (*instance_to_ppp_map)[instance] = browser_ppp; |
| } |
| |
| void UnsetBrowserPppForInstance(PP_Instance instance) { |
| if (NULL == instance_to_ppp_map) { |
| // Something major is wrong here. We are deleting a map entry |
| // when there is no map. |
| NACL_NOTREACHED(); |
| return; |
| } |
| // Erase the instance from the map. |
| instance_to_ppp_map->erase(instance); |
| // If there are no more instances alive, remove the map. |
| if (instance_to_ppp_map->size() == 0) { |
| delete instance_to_ppp_map; |
| instance_to_ppp_map = NULL; |
| } |
| } |
| |
| BrowserPpp* LookupBrowserPppForInstance(PP_Instance instance) { |
| if (NULL == instance_to_ppp_map) { |
| return NULL; |
| } |
| std::map<PP_Instance, BrowserPpp*>::const_iterator iter = |
| instance_to_ppp_map->find(instance); |
| if (iter == instance_to_ppp_map->end()) |
| return NULL; |
| return iter->second; |
| } |
| |
| void SetModuleIdForSrpcChannel(NaClSrpcChannel* channel, PP_Module module_id) { |
| // If there was no map, create one. |
| if (NULL == channel_to_module_id_map) { |
| channel_to_module_id_map = new std::map<NaClSrpcChannel*, PP_Module>; |
| } |
| // Add the channel to the map. |
| (*channel_to_module_id_map)[channel] = module_id; |
| } |
| |
| void SetInstanceIdForSrpcChannel(NaClSrpcChannel* channel, |
| PP_Instance instance_id) { |
| if (NULL == channel_to_instance_id_map) { |
| channel_to_instance_id_map = new std::map<NaClSrpcChannel*, PP_Instance>; |
| } |
| (*channel_to_instance_id_map)[channel] = instance_id; |
| } |
| |
| void UnsetModuleIdForSrpcChannel(NaClSrpcChannel* channel) { |
| if (NULL == channel_to_module_id_map) { |
| // Something major is wrong here. We are deleting a map entry |
| // when there is no map. |
| NACL_NOTREACHED(); |
| return; |
| } |
| // Erase the channel from the map. |
| channel_to_module_id_map->erase(channel); |
| // If there are no more channels alive, remove the map. |
| if (channel_to_module_id_map->size() == 0) { |
| delete channel_to_module_id_map; |
| channel_to_module_id_map = NULL; |
| } |
| } |
| |
| void UnsetInstanceIdForSrpcChannel(NaClSrpcChannel* channel) { |
| if (NULL == channel_to_instance_id_map) { |
| NACL_NOTREACHED(); |
| return; |
| } |
| channel_to_instance_id_map->erase(channel); |
| if (channel_to_instance_id_map->size() == 0) { |
| delete channel_to_module_id_map; |
| channel_to_module_id_map = NULL; |
| } |
| } |
| |
| PP_Module LookupModuleIdForSrpcChannel(NaClSrpcChannel* channel) { |
| if (NULL == channel_to_module_id_map) { |
| return 0; |
| } |
| std::map<NaClSrpcChannel*, PP_Module>::const_iterator iter = |
| channel_to_module_id_map->find(channel); |
| if (iter == channel_to_module_id_map->end()) { |
| return 0; |
| } |
| return iter->second; |
| } |
| |
| PP_Instance LookupInstanceIdForSrpcChannel(NaClSrpcChannel* channel) { |
| if (NULL == channel_to_instance_id_map) { |
| return 0; |
| } |
| std::map<NaClSrpcChannel*, PP_Instance>::const_iterator iter = |
| channel_to_instance_id_map->find(channel); |
| if (iter == channel_to_instance_id_map->end()) { |
| return 0; |
| } |
| return iter->second; |
| } |
| |
| NaClSrpcChannel* GetMainSrpcChannel(NaClSrpcRpc* upcall_rpc) { |
| // The upcall channel's server_instance_data member is initialized to point |
| // to the main channel for this instance. Here it is retrieved to use in |
| // constructing a RemoteCallbackInfo. |
| return static_cast<NaClSrpcChannel*>( |
| upcall_rpc->channel->server_instance_data); |
| } |
| |
| NaClSrpcChannel* GetMainSrpcChannel(PP_Instance instance) { |
| BrowserPpp* proxy = LookupBrowserPppForInstance(instance); |
| if (NULL == proxy) |
| return NULL; |
| return proxy->main_channel(); |
| } |
| |
| void CleanUpAfterDeadNexe(PP_Instance instance) { |
| DebugPrintf("CleanUpAfterDeadNexe\n"); |
| BrowserPpp* proxy = LookupBrowserPppForInstance(instance); |
| if (NULL == proxy) |
| return; |
| proxy->plugin()->ReportDeadNexe(); // Shuts down and deletes the proxy. |
| } |
| |
| void SetPPBGetInterface(PPB_GetInterface get_interface_function, |
| bool allow_dev_interfaces, |
| bool allow_3d_interfaces) { |
| get_interface = get_interface_function; |
| enable_dev_interfaces = allow_dev_interfaces; |
| enable_3d_interfaces = allow_3d_interfaces; |
| } |
| |
| const void* GetBrowserInterface(const char* interface_name) { |
| // Reject suspiciously long interface strings. |
| const size_t kMaxLength = 1024; |
| if (NULL == memchr(interface_name, '\0', kMaxLength)) { |
| return NULL; |
| } |
| // If dev interface is not enabled, reject interfaces containing "(Dev)" |
| if (!enable_dev_interfaces && strstr(interface_name, "(Dev)") != NULL) { |
| return NULL; |
| } |
| if (!enable_3d_interfaces) { |
| static const char* disabled_interface_names[] = { |
| PPB_GRAPHICS_3D_INTERFACE, |
| PPB_GRAPHICS_3D_TRUSTED_INTERFACE, |
| PPB_GLES_CHROMIUM_TEXTURE_MAPPING_DEV_INTERFACE, |
| PPB_OPENGLES2_INTERFACE, |
| PPB_OPENGLES2_INSTANCEDARRAYS_INTERFACE, |
| PPB_OPENGLES2_FRAMEBUFFERBLIT_INTERFACE, |
| PPB_OPENGLES2_FRAMEBUFFERMULTISAMPLE_INTERFACE, |
| PPB_OPENGLES2_CHROMIUMENABLEFEATURE_INTERFACE, |
| PPB_OPENGLES2_CHROMIUMMAPSUB_INTERFACE, |
| PPB_OPENGLES2_QUERY_INTERFACE, |
| PPB_LAYER_COMPOSITOR_DEV_INTERFACE |
| }; |
| for (size_t i = 0; i < NACL_ARRAY_SIZE(disabled_interface_names); i++) { |
| if (strcmp(interface_name, disabled_interface_names[i]) == 0) |
| return NULL; |
| } |
| } |
| return (*get_interface)(interface_name); |
| } |
| |
| const void* GetBrowserInterfaceSafe(const char* interface_name) { |
| const void* ppb_interface = GetBrowserInterface(interface_name); |
| if (NULL == ppb_interface) |
| DebugPrintf("PPB_GetInterface: %s not found\n", interface_name); |
| CHECK(NULL != ppb_interface); |
| return ppb_interface; |
| } |
| |
| const PPB_Core* PPBCoreInterface() { |
| static const PPB_Core* ppb = static_cast<const PPB_Core*>( |
| GetBrowserInterfaceSafe(PPB_CORE_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_Graphics2D* PPBGraphics2DInterface() { |
| static const PPB_Graphics2D* ppb = static_cast<const PPB_Graphics2D*>( |
| GetBrowserInterfaceSafe(PPB_GRAPHICS_2D_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_Graphics3D* PPBGraphics3DInterface() { |
| static const PPB_Graphics3D* ppb = static_cast<const PPB_Graphics3D*>( |
| GetBrowserInterfaceSafe(PPB_GRAPHICS_3D_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_Graphics3DTrusted* PPBGraphics3DTrustedInterface() { |
| static const PPB_Graphics3DTrusted* ppb = |
| static_cast<const PPB_Graphics3DTrusted*>( |
| GetBrowserInterfaceSafe(PPB_GRAPHICS_3D_TRUSTED_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_HostResolver_Private* PPBHostResolverPrivateInterface() { |
| static const PPB_HostResolver_Private* ppb = |
| static_cast<const PPB_HostResolver_Private*>( |
| GetBrowserInterfaceSafe(PPB_HOSTRESOLVER_PRIVATE_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_ImageData* PPBImageDataInterface() { |
| static const PPB_ImageData* ppb = static_cast<const PPB_ImageData*>( |
| GetBrowserInterfaceSafe(PPB_IMAGEDATA_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_ImageDataTrusted* PPBImageDataTrustedInterface() { |
| static const PPB_ImageDataTrusted* ppb = |
| static_cast<const PPB_ImageDataTrusted*>( |
| GetBrowserInterfaceSafe(PPB_IMAGEDATA_TRUSTED_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_InputEvent* PPBInputEventInterface() { |
| static const PPB_InputEvent* ppb = static_cast<const PPB_InputEvent*>( |
| GetBrowserInterfaceSafe(PPB_INPUT_EVENT_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_Instance* PPBInstanceInterface() { |
| static const PPB_Instance* ppb = static_cast<const PPB_Instance*>( |
| GetBrowserInterfaceSafe(PPB_INSTANCE_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_KeyboardInputEvent* PPBKeyboardInputEventInterface() { |
| static const PPB_KeyboardInputEvent* ppb = |
| static_cast<const PPB_KeyboardInputEvent*>( |
| GetBrowserInterfaceSafe(PPB_KEYBOARD_INPUT_EVENT_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_Memory_Dev* PPBMemoryInterface() { |
| static const PPB_Memory_Dev* ppb = static_cast<const PPB_Memory_Dev*>( |
| GetBrowserInterfaceSafe(PPB_MEMORY_DEV_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_Messaging* PPBMessagingInterface() { |
| static const PPB_Messaging* ppb = |
| static_cast<const PPB_Messaging*>( |
| GetBrowserInterfaceSafe(PPB_MESSAGING_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_MouseInputEvent* PPBMouseInputEventInterface() { |
| static const PPB_MouseInputEvent* ppb = |
| static_cast<const PPB_MouseInputEvent*>( |
| GetBrowserInterfaceSafe(PPB_MOUSE_INPUT_EVENT_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_NetAddress_Private* PPBNetAddressPrivateInterface() { |
| static const PPB_NetAddress_Private* ppb = |
| static_cast<const PPB_NetAddress_Private*>( |
| GetBrowserInterfaceSafe(PPB_NETADDRESS_PRIVATE_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_NetworkList_Private* PPBNetworkListPrivateInterface() { |
| static const PPB_NetworkList_Private* ppb = |
| static_cast<const PPB_NetworkList_Private*>( |
| GetBrowserInterfaceSafe(PPB_NETWORKLIST_PRIVATE_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_NetworkMonitor_Private* PPBNetworkMonitorPrivateInterface() { |
| static const PPB_NetworkMonitor_Private* ppb = |
| static_cast<const PPB_NetworkMonitor_Private*>( |
| GetBrowserInterfaceSafe(PPB_NETWORKMONITOR_PRIVATE_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_URLLoader* PPBURLLoaderInterface() { |
| static const PPB_URLLoader* ppb = |
| static_cast<const PPB_URLLoader*>( |
| GetBrowserInterfaceSafe(PPB_URLLOADER_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_URLRequestInfo* PPBURLRequestInfoInterface() { |
| static const PPB_URLRequestInfo* ppb = |
| static_cast<const PPB_URLRequestInfo*>( |
| GetBrowserInterfaceSafe(PPB_URLREQUESTINFO_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_URLResponseInfo* PPBURLResponseInfoInterface() { |
| static const PPB_URLResponseInfo* ppb = |
| static_cast<const PPB_URLResponseInfo*>( |
| GetBrowserInterfaceSafe(PPB_URLRESPONSEINFO_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_Var* PPBVarInterface() { |
| static const PPB_Var* ppb = |
| static_cast<const PPB_Var*>( |
| GetBrowserInterfaceSafe(PPB_VAR_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_VarArrayBuffer* PPBVarArrayBufferInterface() { |
| static const PPB_VarArrayBuffer* ppb = |
| static_cast<const PPB_VarArrayBuffer*>( |
| GetBrowserInterfaceSafe(PPB_VAR_ARRAY_BUFFER_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_WheelInputEvent* PPBWheelInputEventInterface() { |
| static const PPB_WheelInputEvent* ppb = |
| static_cast<const PPB_WheelInputEvent*>( |
| GetBrowserInterfaceSafe(PPB_WHEEL_INPUT_EVENT_INTERFACE)); |
| return ppb; |
| } |
| |
| // Dev interfaces. |
| const PPB_FileIO* PPBFileIOInterface() { |
| static const PPB_FileIO* ppb = |
| static_cast<const PPB_FileIO*>( |
| GetBrowserInterfaceSafe(PPB_FILEIO_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_FileRef* PPBFileRefInterface() { |
| static const PPB_FileRef* ppb = |
| static_cast<const PPB_FileRef*>( |
| GetBrowserInterfaceSafe(PPB_FILEREF_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_FileSystem* PPBFileSystemInterface() { |
| static const PPB_FileSystem* ppb = |
| static_cast<const PPB_FileSystem*>( |
| GetBrowserInterfaceSafe(PPB_FILESYSTEM_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_Find_Dev* PPBFindInterface() { |
| static const PPB_Find_Dev* ppb = |
| static_cast<const PPB_Find_Dev*>( |
| GetBrowserInterfaceSafe(PPB_FIND_DEV_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_Font_Dev* PPBFontInterface() { |
| static const PPB_Font_Dev* ppb = |
| static_cast<const PPB_Font_Dev*>( |
| GetBrowserInterfaceSafe(PPB_FONT_DEV_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_Fullscreen* PPBFullscreenInterface() { |
| static const PPB_Fullscreen* ppb = |
| static_cast<const PPB_Fullscreen*>( |
| GetBrowserInterfaceSafe(PPB_FULLSCREEN_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_Gamepad* PPBGamepadInterface() { |
| static const PPB_Gamepad* ppb = |
| static_cast<const PPB_Gamepad*>( |
| GetBrowserInterfaceSafe(PPB_GAMEPAD_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_MouseCursor_1_0* PPBMouseCursorInterface() { |
| static const PPB_MouseCursor_1_0* ppb = |
| static_cast<const PPB_MouseCursor_1_0*>( |
| GetBrowserInterfaceSafe(PPB_MOUSECURSOR_INTERFACE_1_0)); |
| return ppb; |
| } |
| |
| const PPB_MouseLock* PPBMouseLockInterface() { |
| static const PPB_MouseLock* ppb = static_cast<const PPB_MouseLock*>( |
| GetBrowserInterfaceSafe(PPB_MOUSELOCK_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_Testing_Dev* PPBTestingInterface() { |
| static const PPB_Testing_Dev* ppb = |
| static_cast<const PPB_Testing_Dev*>( |
| GetBrowserInterfaceSafe(PPB_TESTING_DEV_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_View* PPBViewInterface() { |
| static const PPB_View* ppb = |
| static_cast<const PPB_View*>( |
| GetBrowserInterfaceSafe(PPB_VIEW_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_WebSocket* PPBWebSocketInterface() { |
| static const PPB_WebSocket* ppb = |
| static_cast<const PPB_WebSocket*>( |
| GetBrowserInterfaceSafe(PPB_WEBSOCKET_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_Zoom_Dev* PPBZoomInterface() { |
| static const PPB_Zoom_Dev* ppb = |
| static_cast<const PPB_Zoom_Dev*>( |
| GetBrowserInterfaceSafe(PPB_ZOOM_DEV_INTERFACE)); |
| return ppb; |
| } |
| |
| // Private interfaces. |
| const PPB_TCPServerSocket_Private* PPBTCPServerSocketPrivateInterface() { |
| static const PPB_TCPServerSocket_Private* ppb = |
| static_cast<const PPB_TCPServerSocket_Private*>( |
| GetBrowserInterfaceSafe(PPB_TCPSERVERSOCKET_PRIVATE_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_TCPSocket_Private* PPBTCPSocketPrivateInterface() { |
| static const PPB_TCPSocket_Private* ppb = |
| static_cast<const PPB_TCPSocket_Private*>( |
| GetBrowserInterfaceSafe(PPB_TCPSOCKET_PRIVATE_INTERFACE)); |
| return ppb; |
| } |
| |
| const PPB_UDPSocket_Private* PPBUDPSocketPrivateInterface() { |
| static const PPB_UDPSocket_Private* ppb = |
| static_cast<const PPB_UDPSocket_Private*>( |
| GetBrowserInterfaceSafe(PPB_UDPSOCKET_PRIVATE_INTERFACE)); |
| return ppb; |
| } |
| |
| } // namespace ppapi_proxy |