blob: cb2f837bb5a0042e37eac4d5458650bbf5442b3c [file] [log] [blame]
// 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.
//
// Implements the untrusted side of the PPB_GetInterface method.
#include "native_client/src/shared/ppapi_proxy/plugin_globals.h"
#include <stdlib.h>
#include <string.h>
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_audio.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_audio_config.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_buffer.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_core.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_file_io.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_file_ref.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_file_system.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_find.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_font.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_fullscreen.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_gamepad.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_graphics_2d.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_graphics_3d.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_host_resolver_private.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_image_data.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_input_event.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_instance.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_memory.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_messaging.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_mouse_cursor.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_mouse_lock.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_net_address_private.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_network_list_private.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_network_monitor_private.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_tcp_server_socket_private.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_tcp_socket_private.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_testing.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_udp_socket_private.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_url_loader.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_url_request_info.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_url_response_info.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_var.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_view.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_websocket.h"
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_zoom.h"
#include "native_client/src/shared/ppapi_proxy/untrusted/srpcgen/ppb_rpc.h"
#include "native_client/src/shared/ppapi_proxy/utility.h"
namespace ppapi_proxy {
namespace {
struct InterfaceMapElement {
const char* name;
const void* ppb_interface;
bool needs_browser_check;
};
// List of interfaces that have at least partial proxy support.
InterfaceMapElement interface_map[] = {
{ PPB_AUDIO_INTERFACE, PluginAudio::GetInterface(), true },
{ PPB_AUDIO_CONFIG_INTERFACE, PluginAudioConfig::GetInterface(), true },
{ PPB_AUDIO_CONFIG_INTERFACE_1_0, PluginAudioConfig::GetInterface1_0(),
true },
{ PPB_CORE_INTERFACE, PluginCore::GetInterface(), true },
{ PPB_MOUSECURSOR_INTERFACE_1_0, PluginMouseCursor::GetInterface(),
true },
{ PPB_FILEIO_INTERFACE, PluginFileIO::GetInterface(), true },
{ PPB_FILEREF_INTERFACE, PluginFileRef::GetInterface(), true },
{ PPB_FILESYSTEM_INTERFACE, PluginFileSystem::GetInterface(), true },
{ PPB_FIND_DEV_INTERFACE, PluginFind::GetInterface(), true },
{ PPB_FONT_DEV_INTERFACE, PluginFont::GetInterface(), true },
{ PPB_FULLSCREEN_INTERFACE, PluginFullscreen::GetInterface(), true },
{ PPB_GAMEPAD_INTERFACE, PluginGamepad::GetInterface(), true },
{ PPB_GRAPHICS_2D_INTERFACE, PluginGraphics2D::GetInterface(), true },
{ PPB_GRAPHICS_3D_INTERFACE, PluginGraphics3D::GetInterface(), true },
{ PPB_HOSTRESOLVER_PRIVATE_INTERFACE,
PluginHostResolverPrivate::GetInterface(), true },
{ PPB_IMAGEDATA_INTERFACE, PluginImageData::GetInterface(), true },
{ PPB_INPUT_EVENT_INTERFACE, PluginInputEvent::GetInterface(), true },
{ PPB_INSTANCE_INTERFACE, PluginInstance::GetInterface(), true },
{ PPB_KEYBOARD_INPUT_EVENT_INTERFACE,
PluginInputEvent::GetKeyboardInterface(), true },
{ PPB_KEYBOARD_INPUT_EVENT_DEV_INTERFACE,
PluginInputEvent::GetKeyboardInterface_Dev(), true },
{ PPB_MEMORY_DEV_INTERFACE, PluginMemory::GetInterface(), true },
{ PPB_MESSAGING_INTERFACE, PluginMessaging::GetInterface(), true },
{ PPB_MOUSE_INPUT_EVENT_INTERFACE_1_0,
PluginInputEvent::GetMouseInterface1_0(), true },
{ PPB_MOUSE_INPUT_EVENT_INTERFACE_1_1,
PluginInputEvent::GetMouseInterface1_1(), true },
{ PPB_MOUSELOCK_INTERFACE, PluginMouseLock::GetInterface(), true },
{ PPB_NETADDRESS_PRIVATE_INTERFACE_0_1,
PluginNetAddressPrivate::GetInterface0_1(), true },
{ PPB_NETADDRESS_PRIVATE_INTERFACE_1_0,
PluginNetAddressPrivate::GetInterface1_0(), true },
{ PPB_NETADDRESS_PRIVATE_INTERFACE_1_1,
PluginNetAddressPrivate::GetInterface1_1(), true },
{ PPB_NETWORKLIST_PRIVATE_INTERFACE, PluginNetworkListPrivate::GetInterface(),
true },
{ PPB_NETWORKMONITOR_PRIVATE_INTERFACE,
PluginNetworkMonitorPrivate::GetInterface(), true },
{ PPB_OPENGLES2_INTERFACE_1_0, PluginGraphics3D::GetOpenGLESInterface(),
true },
{ PPB_OPENGLES2_INSTANCEDARRAYS_INTERFACE_1_0,
PluginGraphics3D::GetOpenGLESInstancedArraysInterface(),
true },
{ PPB_OPENGLES2_FRAMEBUFFERBLIT_INTERFACE_1_0,
PluginGraphics3D::GetOpenGLESFramebufferBlitInterface(),
true },
{ PPB_OPENGLES2_FRAMEBUFFERMULTISAMPLE_INTERFACE_1_0,
PluginGraphics3D::GetOpenGLESFramebufferMultisampleInterface(),
true },
{ PPB_OPENGLES2_CHROMIUMENABLEFEATURE_INTERFACE_1_0,
PluginGraphics3D::GetOpenGLESChromiumEnableFeatureInterface(),
true },
{ PPB_OPENGLES2_CHROMIUMMAPSUB_INTERFACE_1_0,
PluginGraphics3D::GetOpenGLESChromiumMapSubInterface(),
true },
{ PPB_OPENGLES2_QUERY_INTERFACE_1_0,
PluginGraphics3D::GetOpenGLESQueryInterface(),
true },
{ PPB_TCPSERVERSOCKET_PRIVATE_INTERFACE,
PluginTCPServerSocketPrivate::GetInterface(),
true },
{ PPB_TCPSOCKET_PRIVATE_INTERFACE_0_4,
PluginTCPSocketPrivate::GetInterface0_4(), true },
{ PPB_TCPSOCKET_PRIVATE_INTERFACE_0_3,
PluginTCPSocketPrivate::GetInterface0_3(), true },
{ PPB_TESTING_DEV_INTERFACE_0_9, PluginTesting::GetInterface(), true },
{ PPB_TESTING_DEV_INTERFACE, PluginTesting::GetInterface(), true },
{ PPB_UDPSOCKET_PRIVATE_INTERFACE_0_2,
PluginUDPSocketPrivate::GetInterface0_2(), true },
{ PPB_UDPSOCKET_PRIVATE_INTERFACE_0_3,
PluginUDPSocketPrivate::GetInterface0_3(), true },
{ PPB_UDPSOCKET_PRIVATE_INTERFACE_0_4,
PluginUDPSocketPrivate::GetInterface0_4(), true },
{ PPB_URLLOADER_INTERFACE, PluginURLLoader::GetInterface(), true },
{ PPB_URLREQUESTINFO_INTERFACE, PluginURLRequestInfo::GetInterface(), true },
{ PPB_URLRESPONSEINFO_INTERFACE, PluginURLResponseInfo::GetInterface(),
true },
{ PPB_VAR_ARRAY_BUFFER_INTERFACE, PluginVar::GetArrayBufferInterface(),
true },
{ PPB_VAR_INTERFACE, PluginVar::GetInterface(), true },
{ PPB_VAR_INTERFACE_1_0, PluginVar::GetInterface1_0(), true },
{ PPB_VIEW_INTERFACE, PluginView::GetInterface(), true },
{ PPB_WEBSOCKET_INTERFACE, PluginWebSocket::GetInterface(),
true },
{ PPB_WHEEL_INPUT_EVENT_INTERFACE, PluginInputEvent::GetWheelInterface(),
true },
{ PPB_ZOOM_DEV_INTERFACE, PluginZoom::GetInterface(), true },
};
} // namespace
// Returns the pointer to the interface proxy or NULL if not yet supported.
// On the first invocation for a given interface that has proxy support,
// also confirms over RPC that the browser indeed exports this interface.
// Returns NULL otherwise.
const void* GetBrowserInterface(const char* interface_name) {
DebugPrintf("PPB_GetInterface('%s')\n", interface_name);
const void* ppb_interface = NULL;
int index = -1;
// The interface map is so small that anything but a linear search would be an
// overkill, especially since the keys are macros and might not sort in any
// obvious order relative to the name.
for (size_t i = 0; i < NACL_ARRAY_SIZE(interface_map); ++i) {
if (strcmp(interface_name, interface_map[i].name) == 0) {
ppb_interface = interface_map[i].ppb_interface;
index = i;
break;
}
}
DebugPrintf("PPB_GetInterface('%s'): %p\n", interface_name, ppb_interface);
if (index == -1 || ppb_interface == NULL)
return NULL;
if (!interface_map[index].needs_browser_check)
return ppb_interface;
int32_t browser_exports_interface;
NaClSrpcError srpc_result =
PpbRpcClient::PPB_GetInterface(GetMainSrpcChannel(),
const_cast<char*>(interface_name),
&browser_exports_interface);
DebugPrintf("PPB_GetInterface('%s'): %s\n",
interface_name, NaClSrpcErrorString(srpc_result));
if (srpc_result != NACL_SRPC_RESULT_OK || !browser_exports_interface) {
interface_map[index].ppb_interface = NULL;
ppb_interface = NULL;
}
interface_map[index].needs_browser_check = false;
return ppb_interface;
}
} // namespace ppapi_proxy