diff options
488 files changed, 53212 insertions, 0 deletions
diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_callback.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_callback.cc new file mode 100644 index 0000000..e93e62f --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_callback.cc @@ -0,0 +1,152 @@ +// 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_callback.h" + +#include <new> + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.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 "ppapi/c/pp_completion_callback.h" +#include "native_client/src/trusted/plugin/plugin.h" +#include "srpcgen/ppp_rpc.h" + +namespace ppapi_proxy { + +namespace { + +bool BytesWereRead(int32_t num_bytes) { + return (num_bytes > 0); +} + +nacl_abi_size_t CastToNaClAbiSize(int32_t result) { + return static_cast<nacl_abi_size_t>(result); +} + +// Data structure used on the browser side to invoke a completion callback +// on the plugin side. +// +// A plugin-side callback is proxied over to the browser side using +// a |callback_id|. This id is then paired with an |srpc_channel| listened to +// by the nexe that supplied the callback. +// +// |read_buffer| is used with callbacks that are invoked on byte reads. +// |check_result_func| is a pointer to a function used to check the +// result of the operation. The semantics of the result value may be different +// depending on how the callback operation was initiated, and +// |check_result_func| provides an abstraction to the semantics. +// |get_size_read_func| is a pointer to a function used to get the +// number of bytes read. The way the number of bytes read +// retrieved/calculated may be different depending on how the callback was +// initiated, and |get_size_read_func| provides the indirection. +struct RemoteCallbackInfo { + NaClSrpcChannel* srpc_channel; + int32_t callback_id; + char* read_buffer; + CheckResultFunc check_result_func; + GetReadSizeFunc get_size_read_func; +}; + +// Calls the remote implementation of a callback on the plugin side. +// Implements a PP_CompletionCallback_Func type that can be used along with an +// instance of a RemoteCallbackInfo as |user_data| to provide a +// PP_CompletionCallback to browser functions. +// +// |remote_callback| is a pointer to a RemoteCallbackInfo, +// deleted after rpc via scoped_ptr. The associated |read_buffer| is also +// deleted. +// |result| is passed by the callback invoker to indicate success or error. +// It is passed as-is to the plugin side callback. +void RunRemoteCallback(void* user_data, int32_t result) { + CHECK(PPBCoreInterface()->IsMainThread()); + DebugPrintf("RunRemoteCallback: result=%"NACL_PRId32"\n", result); + nacl::scoped_ptr<RemoteCallbackInfo> remote_callback( + reinterpret_cast<RemoteCallbackInfo*>(user_data)); + nacl::scoped_array<char> read_buffer(remote_callback->read_buffer); + + // If the proxy is down, the channel is no longer usable for remote calls. + PP_Instance instance = + LookupInstanceIdForSrpcChannel(remote_callback->srpc_channel); + if (LookupBrowserPppForInstance(instance) == NULL) { + DebugPrintf("RunRemoteCallback: proxy=NULL\n", result); + return; + } + + nacl_abi_size_t read_buffer_size = 0; + CheckResultFunc check_result_func = remote_callback->check_result_func; + GetReadSizeFunc get_size_read_func = remote_callback->get_size_read_func; + if ((*check_result_func)(result) && remote_callback->read_buffer != NULL) + read_buffer_size = (*get_size_read_func)(result); + + NaClSrpcError srpc_result = + CompletionCallbackRpcClient::RunCompletionCallback( + remote_callback->srpc_channel, + remote_callback->callback_id, + result, + read_buffer_size, + read_buffer.get()); + DebugPrintf("RunRemoteCallback: %s\n", + NaClSrpcErrorString(srpc_result)); + if (srpc_result == NACL_SRPC_RESULT_INTERNAL) + CleanUpAfterDeadNexe(instance); +} + +} // namespace + +// Builds a RemoteCallbackInfo and returns PP_CompletionCallback corresponding +// to RunRemoteCallback or NULL on failure. +struct PP_CompletionCallback MakeRemoteCompletionCallback( + NaClSrpcChannel* srpc_channel, + int32_t callback_id, + int32_t bytes_to_read, + char** buffer, + CheckResultFunc check_result_func, + GetReadSizeFunc get_size_read_func) { + RemoteCallbackInfo* remote_callback = new(std::nothrow) RemoteCallbackInfo; + if (remote_callback == NULL) // new failed. + return PP_BlockUntilComplete(); + remote_callback->srpc_channel = srpc_channel; + remote_callback->callback_id = callback_id; + remote_callback->read_buffer = NULL; + remote_callback->check_result_func = check_result_func; + remote_callback->get_size_read_func = get_size_read_func; + + if (bytes_to_read > 0 && buffer != NULL) { + *buffer = new(std::nothrow) char[bytes_to_read]; + if (*buffer == NULL) // new failed. + return PP_BlockUntilComplete(); + remote_callback->read_buffer = *buffer; + } + + return PP_MakeOptionalCompletionCallback( + RunRemoteCallback, remote_callback); +} + +struct PP_CompletionCallback MakeRemoteCompletionCallback( + NaClSrpcChannel* srpc_channel, + int32_t callback_id, + int32_t bytes_to_read, + char** buffer) { + return MakeRemoteCompletionCallback(srpc_channel, callback_id, bytes_to_read, + buffer, BytesWereRead, CastToNaClAbiSize); +} + +struct PP_CompletionCallback MakeRemoteCompletionCallback( + NaClSrpcChannel* srpc_channel, + int32_t callback_id) { + return MakeRemoteCompletionCallback(srpc_channel, callback_id, 0, NULL); +} + +void DeleteRemoteCallbackInfo(struct PP_CompletionCallback callback) { + nacl::scoped_ptr<RemoteCallbackInfo> remote_callback( + reinterpret_cast<RemoteCallbackInfo*>(callback.user_data)); + nacl::scoped_array<char> read_buffer(remote_callback->read_buffer); +} + +} // namespace ppapi_proxy diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_callback.h b/ppapi/native_client/src/shared/ppapi_proxy/browser_callback.h new file mode 100644 index 0000000..1f6b016 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_callback.h @@ -0,0 +1,50 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_CALLBACK_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_CALLBACK_H_ + +#include "native_client/src/include/portability.h" +#include "native_client/src/trusted/service_runtime/include/machine/_types.h" + +struct NaClSrpcChannel; +struct PP_CompletionCallback; + +namespace ppapi_proxy { + +// Pointer to function to evaluate the result of a read operation. +typedef bool (*CheckResultFunc)(int32_t result); +// Pointer to function to retrieve/calculate the size read. +typedef nacl_abi_size_t (*GetReadSizeFunc)(int32_t result); + +// Returns a PP_CompletionCallback that will call the remote implementation of +// a callback by |callback_id| on the plugin side on |srpc_channel|. +// This callback allows for optimized synchronous completion. +// Allocates data that will be deleted by the underlying callback function. +// Returns NULL callback on failure. +struct PP_CompletionCallback MakeRemoteCompletionCallback( + NaClSrpcChannel* srpc_channel, + int32_t callback_id); +struct PP_CompletionCallback MakeRemoteCompletionCallback( + NaClSrpcChannel* srpc_channel, + int32_t callback_id, + // For callbacks invoked on a byte read. + int32_t bytes_to_read, + char** buffer); +struct PP_CompletionCallback MakeRemoteCompletionCallback( + NaClSrpcChannel* srpc_channel, + int32_t callback_id, + // For callbacks invoked on a byte read. + int32_t bytes_to_read, + char** buffer, + CheckResultFunc check_result, + GetReadSizeFunc get_size_read_func); + +// If the callback won't be called, use this to clean up the data from +// the function above. +void DeleteRemoteCallbackInfo(struct PP_CompletionCallback callback); + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_CALLBACK_H_ diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_globals.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_globals.cc new file mode 100644 index 0000000..667f344 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_globals.cc @@ -0,0 +1,396 @@ +// 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_globals.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" + +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 plugin_requests_dev_interface = false; + +} // namespace + +// By default, disable developer (Dev) interfaces. To enable developer +// interfaces, set the environment variable NACL_ENABLE_PPAPI_DEV to 1. +// Also, the plugin can request whether or not to enable dev interfaces. +bool DevInterfaceEnabled() { + static bool first = true; + static bool env_dev_enabled = false; + if (first) { + const char *nacl_enable_ppapi_dev = getenv("NACL_ENABLE_PPAPI_DEV"); + if (NULL != nacl_enable_ppapi_dev) { + int v = strtol(nacl_enable_ppapi_dev, (char **) 0, 0); + if (v != 0) { + env_dev_enabled = true; + } + } + first = false; + } + return env_dev_enabled || plugin_requests_dev_interface; +} + + +void SetBrowserPppForInstance(PP_Instance instance, BrowserPpp* browser_ppp) { + // If there was no map, create one. + if (instance_to_ppp_map == NULL) { + 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 (instance_to_ppp_map == NULL) { + // 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 (instance_to_ppp_map == NULL) { + return NULL; + } + return (*instance_to_ppp_map)[instance]; +} + +void SetModuleIdForSrpcChannel(NaClSrpcChannel* channel, PP_Module module_id) { + // If there was no map, create one. + if (channel_to_module_id_map == NULL) { + 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 (channel_to_instance_id_map == NULL) { + channel_to_instance_id_map = new std::map<NaClSrpcChannel*, PP_Instance>; + } + (*channel_to_instance_id_map)[channel] = instance_id; +} + +void UnsetModuleIdForSrpcChannel(NaClSrpcChannel* channel) { + if (channel_to_module_id_map == NULL) { + // 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 (channel_to_instance_id_map == NULL) { + 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 (channel_to_module_id_map == NULL) { + return 0; + } + return (*channel_to_module_id_map)[channel]; +} + +PP_Module LookupInstanceIdForSrpcChannel(NaClSrpcChannel* channel) { + if (channel_to_instance_id_map == NULL) { + return 0; + } + return (*channel_to_instance_id_map)[channel]; +} + +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) { + return LookupBrowserPppForInstance(instance)->main_channel(); +} + +void CleanUpAfterDeadNexe(PP_Instance instance) { + DebugPrintf("CleanUpAfterDeadNexe\n"); + BrowserPpp* proxy = LookupBrowserPppForInstance(instance); + if (proxy == NULL) + return; + proxy->ShutdownModule(); + proxy->plugin()->ReportDeadNexe(); // Deletes the proxy. +} + +void SetPPBGetInterface(PPB_GetInterface get_interface_function, + bool dev_interface) { + get_interface = get_interface_function; + plugin_requests_dev_interface = dev_interface; +} + +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 (!DevInterfaceEnabled() && strstr(interface_name, "(Dev)") != NULL) { + return NULL; + } + return (*get_interface)(interface_name); +} + +const void* GetBrowserInterfaceSafe(const char* interface_name) { + const void* ppb_interface = GetBrowserInterface(interface_name); + if (ppb_interface == NULL) + DebugPrintf("PPB_GetInterface: %s not found\n", interface_name); + CHECK(ppb_interface != NULL); + 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_Dev* PPBGraphics3DInterface() { + static const PPB_Graphics3D_Dev* ppb = static_cast<const PPB_Graphics3D_Dev*>( + GetBrowserInterfaceSafe(PPB_GRAPHICS_3D_DEV_INTERFACE)); + return ppb; +} + +const PPB_Graphics3DTrusted_Dev* PPBGraphics3DTrustedInterface() { + static const PPB_Graphics3DTrusted_Dev* ppb = + static_cast<const PPB_Graphics3DTrusted_Dev*>( + GetBrowserInterfaceSafe(PPB_GRAPHICS_3D_TRUSTED_DEV_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_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_WheelInputEvent* PPBWheelInputEventInterface() { + static const PPB_WheelInputEvent* ppb = + static_cast<const PPB_WheelInputEvent*>( + GetBrowserInterfaceSafe(PPB_WHEEL_INPUT_EVENT_INTERFACE)); + return ppb; +} + +// Dev interfaces. +const PPB_CursorControl_Dev* PPBCursorControlInterface() { + static const PPB_CursorControl_Dev* ppb = + static_cast<const PPB_CursorControl_Dev*>( + GetBrowserInterfaceSafe(PPB_CURSOR_CONTROL_DEV_INTERFACE)); + return ppb; +} + +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_Scrollbar_Dev* PPBScrollbarInterface() { + static const PPB_Scrollbar_Dev* ppb = + static_cast<const PPB_Scrollbar_Dev*>( + GetBrowserInterfaceSafe(PPB_SCROLLBAR_DEV_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_Widget_Dev* PPBWidgetInterface() { + static const PPB_Widget_Dev* ppb = + static_cast<const PPB_Widget_Dev*>( + GetBrowserInterfaceSafe(PPB_WIDGET_DEV_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_PDF* PPBPDFInterface() { + static const PPB_PDF* ppb = + static_cast<const PPB_PDF*>( + GetBrowserInterfaceSafe(PPB_PDF_INTERFACE)); + return ppb; +} + +} // namespace ppapi_proxy diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_globals.h b/ppapi/native_client/src/shared/ppapi_proxy/browser_globals.h new file mode 100644 index 0000000..b90ee90 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_globals.h @@ -0,0 +1,132 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_GLOBALS_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_GLOBALS_H_ + +#include "ppapi/c/dev/ppb_cursor_control_dev.h" +#include "ppapi/c/dev/ppb_find_dev.h" +#include "ppapi/c/dev/ppb_graphics_3d_dev.h" +#include "ppapi/c/dev/ppb_graphics_3d_trusted_dev.h" +#include "ppapi/c/dev/ppb_font_dev.h" +#include "ppapi/c/dev/ppb_memory_dev.h" +#include "ppapi/c/dev/ppb_scrollbar_dev.h" +#include "ppapi/c/dev/ppb_testing_dev.h" +#include "ppapi/c/dev/ppb_var_deprecated.h" +#include "ppapi/c/dev/ppb_widget_dev.h" +#include "ppapi/c/dev/ppb_zoom_dev.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/ppb.h" +#include "ppapi/c/ppb_core.h" +#include "ppapi/c/ppb_file_io.h" +#include "ppapi/c/ppb_file_ref.h" +#include "ppapi/c/ppb_file_system.h" +#include "ppapi/c/ppb_graphics_2d.h" +#include "ppapi/c/ppb_image_data.h" +#include "ppapi/c/ppb_input_event.h" +#include "ppapi/c/ppb_instance.h" +#include "ppapi/c/ppb_messaging.h" +#include "ppapi/c/ppb_url_loader.h" +#include "ppapi/c/ppb_url_request_info.h" +#include "ppapi/c/ppb_url_response_info.h" +#include "ppapi/c/ppb_var.h" +#include "ppapi/c/private/ppb_pdf.h" +#include "ppapi/c/trusted/ppb_image_data_trusted.h" + +struct NaClSrpcRpc; +struct NaClSrpcChannel; + +namespace ppapi_proxy { + +// These functions handle the browser-side (trusted code) mapping of a browser +// Instance to instance-specific data, such as the SRPC communication channel. +// These functions are called by the in-browser (trusted) plugin code, and are +// always called from the main (foreground, UI, ...) thread. As such, they are +// not thread-safe (they do not need to be). + +// BrowserPpp keeps browser side PPP_Instance specific information, such as the +// channel used to talk to the instance. +class BrowserPpp; + +// Returns true if the PPAPI Developer interface is enabled. +// To enable, set the environment variable NACL_ENABLE_PPAPI_DEV=1 +// Note: Developer interfaces are _not_ enabled by default. +bool DevInterfaceEnabled(); + +// Associate a particular BrowserPpp with a PP_Instance value. This allows the +// browser side to look up information it needs to communicate with the stub. +void SetBrowserPppForInstance(PP_Instance instance, + BrowserPpp* browser_ppp); +// When an instance is destroyed, this is called to remove the association, as +// the stub will be destroyed by a call to Shutdown. +void UnsetBrowserPppForInstance(PP_Instance instance); +// Gets the BrowserPpp information remembered for a particular instance. +BrowserPpp* LookupBrowserPppForInstance(PP_Instance instance); + +// To keep track of memory allocated by a particular module, we need to remember +// the PP_Module corresponding to a particular NaClSrpcChannel*. +void SetModuleIdForSrpcChannel(NaClSrpcChannel* channel, PP_Module module_id); +// To call remote callbacks only when the proxy is up and running, we need to +// remember the PP_Instance corresponding to a particular NaClSrpcChannel*. +void SetInstanceIdForSrpcChannel(NaClSrpcChannel* channel, + PP_Instance instance_id); +// Removes the association with a given channel. +void UnsetModuleIdForSrpcChannel(NaClSrpcChannel* channel); +void UnsetInstanceIdForSrpcChannel(NaClSrpcChannel* channel); +// Looks up the association with a given channel. +PP_Module LookupModuleIdForSrpcChannel(NaClSrpcChannel* channel); +PP_Instance LookupInstanceIdForSrpcChannel(NaClSrpcChannel* channel); + +// Helpers for getting a pointer to the "main channel" for a specific nexe. +NaClSrpcChannel* GetMainSrpcChannel(NaClSrpcRpc* upcall_rpc); +NaClSrpcChannel* GetMainSrpcChannel(PP_Instance); + +// Invalidates the proxy and alerts the plugin about a dead nexe. +void CleanUpAfterDeadNexe(PP_Instance instance); + +// Support for getting PPB_ browser interfaces. +// Safe version CHECK's for NULL. +void SetPPBGetInterface(PPB_GetInterface get_interface_function, + bool dev_interface); +const void* GetBrowserInterface(const char* interface_name); +const void* GetBrowserInterfaceSafe(const char* interface_name); +// Functions marked "shared" are to be provided by both the browser and the +// plugin side of the proxy, so they can be used by the shared proxy code +// under both trusted and untrusted compilation. +const PPB_Core* PPBCoreInterface(); // shared +const PPB_CursorControl_Dev* PPBCursorControlInterface(); +const PPB_FileIO* PPBFileIOInterface(); +const PPB_FileRef* PPBFileRefInterface(); +const PPB_FileSystem* PPBFileSystemInterface(); +const PPB_Find_Dev* PPBFindInterface(); +const PPB_Font_Dev* PPBFontInterface(); +const PPB_Graphics2D* PPBGraphics2DInterface(); +const PPB_Graphics3D_Dev* PPBGraphics3DInterface(); +const PPB_Graphics3DTrusted_Dev* PPBGraphics3DTrustedInterface(); +const PPB_ImageData* PPBImageDataInterface(); +const PPB_ImageDataTrusted* PPBImageDataTrustedInterface(); +const PPB_InputEvent* PPBInputEventInterface(); +const PPB_Instance* PPBInstanceInterface(); +const PPB_KeyboardInputEvent* PPBKeyboardInputEventInterface(); +const PPB_Memory_Dev* PPBMemoryInterface(); // shared +const PPB_MouseInputEvent* PPBMouseInputEventInterface(); +const PPB_Messaging* PPBMessagingInterface(); +const PPB_PDF* PPBPDFInterface(); +const PPB_Scrollbar_Dev* PPBScrollbarInterface(); +const PPB_Testing_Dev* PPBTestingInterface(); +const PPB_URLLoader* PPBURLLoaderInterface(); +const PPB_URLRequestInfo* PPBURLRequestInfoInterface(); +const PPB_URLResponseInfo* PPBURLResponseInfoInterface(); +const PPB_Var* PPBVarInterface(); // shared +const PPB_WheelInputEvent* PPBWheelInputEventInterface(); +const PPB_Widget_Dev* PPBWidgetInterface(); +const PPB_Zoom_Dev* PPBZoomInterface(); + +// PPAPI constants used in the proxy. +extern const PP_Resource kInvalidResourceId; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_GLOBALS_H_ diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_nacl_file_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_nacl_file_rpc_server.cc new file mode 100644 index 0000000..895dbd0 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_nacl_file_rpc_server.cc @@ -0,0 +1,82 @@ +// 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. +// +// SRPC-abstraction wrappers around NaclFile functions. + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/browser_callback.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/ppapi_proxy/browser_ppp.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 "native_client/src/trusted/service_runtime/include/sys/fcntl.h" +#include "ppapi/c/pp_completion_callback.h" +#include "srpcgen/ppb_rpc.h" + +using ppapi_proxy::MakeRemoteCompletionCallback; +using ppapi_proxy::LookupBrowserPppForInstance; +using ppapi_proxy::DebugPrintf; +using ppapi_proxy::DevInterfaceEnabled; + +void NaClFileRpcServer::StreamAsFile( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Instance instance, + char* url, + int32_t callback_id) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_CompletionCallback remote_callback = + MakeRemoteCompletionCallback(rpc->channel, callback_id); + if (remote_callback.func == NULL) + return; + + plugin::Plugin* plugin = LookupBrowserPppForInstance(instance)->plugin(); + // Will always call the callback on success or failure. + bool success = plugin->StreamAsFile(url, remote_callback); + DebugPrintf("NaClFile::StreamAsFile: success=%d\n", success); + + rpc->result = NACL_SRPC_RESULT_OK; +} + +// GetFileDesc() will only provide file descriptors if the PPAPI Dev interface +// is enabled. By default, it is _not_ enabled. See DevInterfaceEnabled() for +// information on how to enable. +void NaClFileRpcServer::GetFileDesc( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Instance instance, + char* url, + // outputs + NaClSrpcImcDescType* file_desc) { + nacl::DescWrapperFactory factory; + nacl::scoped_ptr<nacl::DescWrapper> desc_wrapper(factory.MakeInvalid()); + // NOTE: |runner| must be created after the desc_wrapper, so it's destroyed + // first. This way ~NaClSrpcClosureRunner gets to transmit the underlying + // NaClDesc before it is unref'ed and freed by ~DescWrapper. + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + if (DevInterfaceEnabled()) { + plugin::Plugin* plugin = LookupBrowserPppForInstance(instance)->plugin(); + int32_t posix_file_desc = plugin->GetPOSIXFileDesc(url); + DebugPrintf("NaClFile::GetFileDesc: posix_file_desc=%"NACL_PRId32"\n", + posix_file_desc); + + desc_wrapper.reset(factory.MakeFileDesc(posix_file_desc, + NACL_ABI_O_RDONLY)); + if (desc_wrapper.get() == NULL) + return; + } else { + DebugPrintf("NaClFile::GetFileDesc is disabled (and experimental.)\n"); + // Return invalid descriptor (from factory.MakeInvalid() above.) + } + *file_desc = desc_wrapper->desc(); + rpc->result = NACL_SRPC_RESULT_OK; +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_audio_config_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_audio_config_rpc_server.cc new file mode 100644 index 0000000..7a8ced3 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_audio_config_rpc_server.cc @@ -0,0 +1,128 @@ +// Copyright (c) 2010 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. +// +// SRPC-abstraction wrappers around PPB_AudioConfig functions. + +#include "ppapi/c/ppb_audio_config.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "srpcgen/ppb_rpc.h" + +using ppapi_proxy::DebugPrintf; + +static const PPB_AudioConfig* GetAudioConfigInterface() { + static const PPB_AudioConfig* audioConfig = + static_cast<const PPB_AudioConfig*> + (ppapi_proxy::GetBrowserInterface(PPB_AUDIO_CONFIG_INTERFACE)); + return audioConfig; +} + +void PpbAudioConfigRpcServer::PPB_AudioConfig_CreateStereo16Bit( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t sample_rate, + int32_t sample_frame_count, + PP_Resource* resource) { + NaClSrpcClosureRunner runner(done); + const PPB_AudioConfig* audio = GetAudioConfigInterface(); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + if (NULL == audio) { + return; + } + if (NULL == resource) { + return; + } + *resource = audio->CreateStereo16Bit( + instance, static_cast<PP_AudioSampleRate>(sample_rate), + sample_frame_count); + DebugPrintf("PPB_AudioConfig::CreateStereo16Bit: resource=%"NACL_PRIu32"\n", + *resource); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbAudioConfigRpcServer::PPB_AudioConfig_RecommendSampleFrameCount( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + int32_t sample_rate, + int32_t request_sample_frame_count, + int32_t* sample_frame_count) { + NaClSrpcClosureRunner runner(done); + const PPB_AudioConfig* audio = GetAudioConfigInterface(); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + if (NULL == audio) { + return; + } + *sample_frame_count = audio->RecommendSampleFrameCount( + static_cast<PP_AudioSampleRate>(sample_rate), + request_sample_frame_count); + DebugPrintf("PPB_AudioConfig::RecommendSampleFrameCount: " + "sample_frame_count=%"NACL_PRIu32"\n", *sample_frame_count); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbAudioConfigRpcServer::PPB_AudioConfig_IsAudioConfig( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* success) { + NaClSrpcClosureRunner runner(done); + const PPB_AudioConfig* audio = GetAudioConfigInterface(); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + if (NULL == audio) { + return; + } + PP_Bool pp_success = audio->IsAudioConfig(resource); + DebugPrintf("PPB_AudioConfig::IsAudioConfig: pp_success=%d\n", pp_success); + *success = (pp_success == PP_TRUE); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbAudioConfigRpcServer::PPB_AudioConfig_GetSampleRate( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* sample_rate) { + NaClSrpcClosureRunner runner(done); + const PPB_AudioConfig* audio = GetAudioConfigInterface(); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + if (NULL == audio) { + return; + } + if (ppapi_proxy::kInvalidResourceId == resource) { + return; + } + if (NULL == sample_rate) { + return; + } + *sample_rate = audio->GetSampleRate(resource); + DebugPrintf("PPB_AudioConfig::GetSampleRate: pp_success=%"NACL_PRIu32"\n", + *sample_rate); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbAudioConfigRpcServer::PPB_AudioConfig_GetSampleFrameCount( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* sample_frame_count) { + NaClSrpcClosureRunner runner(done); + const PPB_AudioConfig* audio = GetAudioConfigInterface(); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + if (NULL == audio) { + return; + } + if (ppapi_proxy::kInvalidResourceId == resource) { + return; + } + if (NULL == sample_frame_count) { + return; + } + *sample_frame_count = audio->GetSampleFrameCount(resource); + DebugPrintf("PPB_AudioConfig::GetSampleFrameCount: " + "sample_frame_count=%"NACL_PRIu32"\n", *sample_frame_count); + rpc->result = NACL_SRPC_RESULT_OK; +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_audio_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_audio_rpc_server.cc new file mode 100644 index 0000000..ce2ed2a --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_audio_rpc_server.cc @@ -0,0 +1,216 @@ +// 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. +// +// SRPC-abstraction wrappers around PPB_Audio functions. + +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/ppapi_proxy/browser_ppp.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "native_client/src/trusted/desc/nacl_desc_invalid.h" +#include "native_client/src/trusted/desc/nacl_desc_wrapper.h" +#include "ppapi/c/ppb_audio.h" +#include "ppapi/c/ppb_audio_config.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/trusted/ppb_audio_trusted.h" +#include "ppapi/cpp/completion_callback.h" +#include "ppapi/cpp/core.h" +#include "ppapi/cpp/module.h" +#include "srpcgen/ppb_rpc.h" +#include "srpcgen/ppp_rpc.h" + +using ppapi_proxy::DebugPrintf; + +namespace { + +const PPB_AudioTrusted* GetAudioTrustedInterface() { + DebugPrintf("GetAudioTrustedInterface\n"); + static const PPB_AudioTrusted* audioTrusted = + static_cast<const PPB_AudioTrusted*> + (ppapi_proxy::GetBrowserInterface(PPB_AUDIO_TRUSTED_INTERFACE)); + return audioTrusted; +} + +const PPB_Audio* GetAudioInterface() { + DebugPrintf("GetAudioInterface\n"); + static const PPB_Audio* audio = + static_cast<const PPB_Audio*> + (ppapi_proxy::GetBrowserInterface(PPB_AUDIO_INTERFACE)); + return audio; +} + +struct StreamCreatedCallbackData { + PP_Instance instance_id; + PP_Resource audio_id; + StreamCreatedCallbackData(PP_Instance i, PP_Resource a) : + instance_id(i), + audio_id(a) { } +}; + +// This completion callback will be invoked when the sync socket and shared +// memory handles become available. +void StreamCreatedCallback(void* user_data, int32_t result) { + DebugPrintf("StreamCreatedCallback: user_data=%p result=%"NACL_PRId32"\n", + user_data, result); + if (NULL == user_data) { + return; + } + nacl::scoped_ptr<StreamCreatedCallbackData> data( + static_cast<StreamCreatedCallbackData*>(user_data)); + if (result < 0) { + return; + } + const PPB_AudioTrusted* audioTrusted = GetAudioTrustedInterface(); + if (NULL == audioTrusted) { + return; + } + int sync_socket_handle; + int shared_memory_handle; + uint32_t shared_memory_size; + if (PP_OK != audioTrusted->GetSyncSocket(data->audio_id, + &sync_socket_handle)) { + return; + } + if (PP_OK != audioTrusted->GetSharedMemory(data->audio_id, + &shared_memory_handle, + &shared_memory_size)) { + return; + } + nacl::DescWrapperFactory factory; + NaClHandle nacl_shm_handle = (NaClHandle)shared_memory_handle; + NaClHandle nacl_sync_handle = (NaClHandle)sync_socket_handle; + nacl::scoped_ptr<nacl::DescWrapper> shm_wrapper(factory.ImportShmHandle( + nacl_shm_handle, shared_memory_size)); + nacl::scoped_ptr<nacl::DescWrapper> socket_wrapper( + factory.ImportSyncSocketHandle(nacl_sync_handle)); + NaClDesc *nacl_shm = NaClDescRef(shm_wrapper->desc()); + NaClDesc *nacl_socket = NaClDescRef(socket_wrapper->desc()); + int r; + r = PppAudioRpcClient::PPP_Audio_StreamCreated( + ppapi_proxy::GetMainSrpcChannel(data->instance_id), + data->audio_id, + nacl_shm, + shared_memory_size, + nacl_socket); +} + +} // namespace + +void PpbAudioRpcServer::PPB_Audio_Create( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + PP_Resource config, + PP_Resource* resource) { + DebugPrintf("PPB_Audio::Create: instance=%"NACL_PRIu32" config=%"NACL_PRIu32 + "\n", instance, config); + NaClSrpcClosureRunner runner(done); + const PPB_AudioTrusted* audio = GetAudioTrustedInterface(); + PP_CompletionCallback callback; + StreamCreatedCallbackData* data; + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + if (ppapi_proxy::kInvalidResourceId == config) { + return; + } + if (NULL == audio) { + return; + } + *resource = audio->CreateTrusted(instance); + DebugPrintf("PPB_Audio::Create: resource=%"NACL_PRIu32"\n", *resource); + PP_Resource audio_id = *resource; + if (ppapi_proxy::kInvalidResourceId == audio_id) { + return; + } + data = new StreamCreatedCallbackData(instance, audio_id); + callback = PP_MakeOptionalCompletionCallback(StreamCreatedCallback, data); + int32_t pp_error = audio->Open(audio_id, config, callback); + DebugPrintf("PPB_Audio::Create: pp_error=%"NACL_PRIu32"\n", pp_error); + // If the Open() call failed, pass failure code and explicitly + // invoke the completion callback, giving it a chance to release data. + if (pp_error != PP_OK_COMPLETIONPENDING) { + PP_RunCompletionCallback(&callback, pp_error); + return; + } + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbAudioRpcServer::PPB_Audio_StartPlayback( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* success) { + DebugPrintf("PPB_Audio::StartPlayback: resource=%"NACL_PRIu32"\n", resource); + NaClSrpcClosureRunner runner(done); + const PPB_Audio* audio = GetAudioInterface(); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + if (NULL == audio) { + *success = false; + return; + } + PP_Bool pp_success = audio->StartPlayback(resource); + DebugPrintf("PPB_Audio::StartPlayback: pp_success=%d\n", pp_success); + *success = (pp_success == PP_TRUE); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbAudioRpcServer::PPB_Audio_StopPlayback( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* success) { + DebugPrintf("PPB_Audio::StopPlayback: resource=%"NACL_PRIu32"\n", resource); + NaClSrpcClosureRunner runner(done); + const PPB_Audio* audio = GetAudioInterface(); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + if (NULL == audio) { + *success = false; + return; + } + PP_Bool pp_success = audio->StopPlayback(resource); + DebugPrintf("PPB_Audio::StopPlayback: pp_success=%d\n", pp_success); + *success = (pp_success == PP_TRUE); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbAudioRpcServer::PPB_Audio_IsAudio( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* success) { + DebugPrintf("PPB_Audio::IsAudio: resource=%"NACL_PRIu32"\n", resource); + NaClSrpcClosureRunner runner(done); + const PPB_Audio* audio = GetAudioInterface(); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + if (NULL == audio) { + *success = false; + return; + } + PP_Bool pp_success = audio->IsAudio(resource); + DebugPrintf("PPB_Audio::IsAudio: pp_success=%d\n", pp_success); + *success = (pp_success == PP_TRUE); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbAudioRpcServer::PPB_Audio_GetCurrentConfig( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + PP_Resource* config) { + DebugPrintf("PPB_Audio::GetCurrentConfig: resource=%"NACL_PRIu32"\n", + resource); + NaClSrpcClosureRunner runner(done); + const PPB_Audio* audio = GetAudioInterface(); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + if (NULL == audio) { + return; + } + if (ppapi_proxy::kInvalidResourceId == resource) { + return; + } + *config = audio->GetCurrentConfig(resource); + DebugPrintf("PPB_Audio::GetCurrentConfig: config=%"NACL_PRIu32"\n", *config); + rpc->result = NACL_SRPC_RESULT_OK; +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_core_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_core_rpc_server.cc new file mode 100644 index 0000000..e58db6f --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_core_rpc_server.cc @@ -0,0 +1,120 @@ +// Copyright (c) 2010 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. +// +// SRPC-abstraction wrappers around PPB_Core functions. + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/src/shared/ppapi_proxy/browser_callback.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/pp_completion_callback.h" +#include "srpcgen/ppb_rpc.h" +#include "srpcgen/upcall.h" + +using ppapi_proxy::DebugPrintf; +using ppapi_proxy::PPBCoreInterface; +using ppapi_proxy::MakeRemoteCompletionCallback; +using ppapi_proxy::GetMainSrpcChannel; + +void PpbCoreRpcServer::PPB_Core_AddRefResource(NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource) { + NaClSrpcClosureRunner runner(done); + PPBCoreInterface()->AddRefResource(resource); + DebugPrintf("PPB_Core::AddRefResource: resource=%"NACL_PRIu32"\n", resource); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbCoreRpcServer::PPB_Core_ReleaseResource(NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource) { + NaClSrpcClosureRunner runner(done); + PPBCoreInterface()->ReleaseResource(resource); + DebugPrintf("PPB_Core::ReleaseResource: resource=%"NACL_PRIu32"\n", + resource); + rpc->result = NACL_SRPC_RESULT_OK; +} + +// MemAlloc and MemFree are handled locally to the plugin, and do not need a +// browser stub. + +void PpbCoreRpcServer::PPB_Core_GetTime(NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + double* time) { + NaClSrpcClosureRunner runner(done); + *time = PPBCoreInterface()->GetTime(); + DebugPrintf("PPB_Core::GetTime: time=%f\n", *time); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbCoreRpcServer::PPB_Core_GetTimeTicks(NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + double* time_ticks) { + NaClSrpcClosureRunner runner(done); + *time_ticks = PPBCoreInterface()->GetTimeTicks(); + DebugPrintf("PPB_Core::GetTimeTicks: time_ticks=%f\n", *time_ticks); + rpc->result = NACL_SRPC_RESULT_OK; +} + +// Release multiple references at once. +void PpbCoreRpcServer::ReleaseResourceMultipleTimes(NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t count) { + NaClSrpcClosureRunner runner(done); + while (count--) + PPBCoreInterface()->ReleaseResource(resource); + rpc->result = NACL_SRPC_RESULT_OK; +} + +// Invoked from main thread. +void PpbCoreRpcServer::PPB_Core_CallOnMainThread( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + int32_t delay_in_milliseconds, + int32_t callback_id, + int32_t result) { + CHECK(PPBCoreInterface()->IsMainThread()); + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_CompletionCallback remote_callback = + MakeRemoteCompletionCallback(rpc->channel, callback_id); + if (remote_callback.func == NULL) + return; // Treat this as a generic SRPC error. + + PPBCoreInterface()->CallOnMainThread( + delay_in_milliseconds, remote_callback, result); + DebugPrintf("PPB_Core::CallOnMainThread_main: " + "delay_in_milliseconds=%"NACL_PRId32"\n", delay_in_milliseconds); + rpc->result = NACL_SRPC_RESULT_OK; +} + + // Invoked from upcall thread. +void PppUpcallRpcServer::PPB_Core_CallOnMainThread( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + int32_t delay_in_milliseconds, + int32_t callback_id, + int32_t result) { + CHECK(!PPBCoreInterface()->IsMainThread()); + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_CompletionCallback remote_callback_on_main = + MakeRemoteCompletionCallback(GetMainSrpcChannel(rpc), callback_id); + if (remote_callback_on_main.func == NULL) + return; // Treat this as a generic SRPC error. + + PPBCoreInterface()->CallOnMainThread( + delay_in_milliseconds, remote_callback_on_main, result); + DebugPrintf("PPB_Core::CallOnMainThread_upcall: " + "delay_in_milliseconds=%"NACL_PRId32"\n", delay_in_milliseconds); + rpc->result = NACL_SRPC_RESULT_OK; +} + +// IsMainThread is handled locally to the plugin, and does not need a browser +// stub. diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_cursor_control_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_cursor_control_rpc_server.cc new file mode 100644 index 0000000..3a17b8f --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_cursor_control_rpc_server.cc @@ -0,0 +1,114 @@ +// 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. +// +// SRPC-abstraction wrappers around PPB_CursorControl_Dev functions. + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "native_client/src/trusted/desc/nacl_desc_wrapper.h" +#include "ppapi/c/dev/ppb_cursor_control_dev.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_point.h" +#include "ppapi/c/ppb_image_data.h" +#include "srpcgen/ppb_rpc.h" + +using ppapi_proxy::DebugPrintf; +using ppapi_proxy::PPBCursorControlInterface; + +void PpbCursorControlRpcServer::PPB_CursorControl_SetCursor( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t type, + PP_Resource custom_image, + nacl_abi_size_t hot_spot_size, char* hot_spot, + int32_t* success) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_Point* pp_hot_spot = NULL; + if (hot_spot_size != 0) { + if (hot_spot_size != sizeof(struct PP_Point)) + return; + pp_hot_spot = reinterpret_cast<struct PP_Point*>(hot_spot); + } + PP_Bool pp_success = PPBCursorControlInterface()->SetCursor( + instance, + static_cast<PP_CursorType_Dev>(type), + custom_image, + pp_hot_spot); + *success = (pp_success == PP_TRUE); + + DebugPrintf("PPB_CursorControl::SetCursor: success=%"NACL_PRId32"\n", + *success); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbCursorControlRpcServer::PPB_CursorControl_LockCursor( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t* success) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_Bool pp_success = PPBCursorControlInterface()->LockCursor(instance); + *success = (pp_success == PP_TRUE); + + DebugPrintf("PPB_CursorControl::LockCursor: success=%"NACL_PRId32"\n", + *success); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbCursorControlRpcServer::PPB_CursorControl_UnlockCursor( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t* success) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_Bool pp_success = PPBCursorControlInterface()->UnlockCursor(instance); + *success = (pp_success == PP_TRUE); + + DebugPrintf("PPB_CursorControl::UnlockCursor: success=%"NACL_PRId32"\n", + *success); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbCursorControlRpcServer::PPB_CursorControl_HasCursorLock( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t* success) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_Bool pp_success = PPBCursorControlInterface()->HasCursorLock(instance); + *success = (pp_success == PP_TRUE); + + DebugPrintf("PPB_CursorControl::HasCursorLock: success=%"NACL_PRId32"\n", + *success); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbCursorControlRpcServer::PPB_CursorControl_CanLockCursor( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t* success) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_Bool pp_success = PPBCursorControlInterface()->CanLockCursor(instance); + *success = (pp_success == PP_TRUE); + + DebugPrintf("PPB_CursorControl::CanLockCursor: success=%"NACL_PRId32"\n", + *success); + rpc->result = NACL_SRPC_RESULT_OK; +} + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_file_io_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_file_io_rpc_server.cc new file mode 100644 index 0000000..e269a23 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_file_io_rpc_server.cc @@ -0,0 +1,310 @@ +// 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 <string.h> +#include <limits> + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/shared/ppapi_proxy/browser_callback.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/pp_file_info.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/ppb_file_io.h" +#include "srpcgen/ppb_rpc.h" + +using ppapi_proxy::DebugPrintf; +using ppapi_proxy::DeleteRemoteCallbackInfo; +using ppapi_proxy::MakeRemoteCompletionCallback; +using ppapi_proxy::PPBFileIOInterface; + +void PpbFileIORpcServer::PPB_FileIO_Create( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // input + PP_Instance instance, + // output + PP_Resource* resource) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_OK; + + *resource = PPBFileIOInterface()->Create(instance); + DebugPrintf("PPB_FileIO::Create: resource=%"NACL_PRIu32"\n", *resource); +} + +// TODO(sanga): Use a caching resource tracker instead of going over the proxy +// to determine if the given resource is a file io. +void PpbFileIORpcServer::PPB_FileIO_IsFileIO( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Resource resource, + // output + int32_t* success) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_OK; + + PP_Bool pp_success = PPBFileIOInterface()->IsFileIO(resource); + DebugPrintf("PPB_FileIO::IsFileIO: pp_success=%d\n", pp_success); + + *success = (pp_success == PP_TRUE); +} + +void PpbFileIORpcServer::PPB_FileIO_Open( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Resource file_io, + PP_Resource file_ref, + int32_t open_flags, + int32_t callback_id, + // output + int32_t* pp_error) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_CompletionCallback remote_callback = + MakeRemoteCompletionCallback(rpc->channel, callback_id); + if (NULL == remote_callback.func) + return; + + *pp_error = PPBFileIOInterface()->Open( + file_io, + file_ref, + open_flags, + remote_callback); + DebugPrintf("PPB_FileIO::Open: pp_error=%"NACL_PRId32"\n", *pp_error); + + if (*pp_error != PP_OK_COMPLETIONPENDING) // Async error. + DeleteRemoteCallbackInfo(remote_callback); + rpc->result = NACL_SRPC_RESULT_OK; +} + +namespace { + +bool IsResultPP_OK(int32_t result) { + return (result == PP_OK); +} + +nacl_abi_size_t SizeOfPP_FileInfo(int32_t /*query_callback_result*/) { + return sizeof(PP_FileInfo); +} + +} // namespace + +void PpbFileIORpcServer::PPB_FileIO_Query( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_io, + int32_t bytes_to_read, + int32_t callback_id, + nacl_abi_size_t* info_bytes, char* info, + int32_t* pp_error) { + // Since PPB_FileIO::Query does not complete synchronously, and we use remote + // completion callback with completion callback table on the untrusted side + // (see browser_callback.h and plugin_callback.h), so the actual file info + // parameter is not used. + UNREFERENCED_PARAMETER(info); + + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + // TODO(sanga): Drop bytes_to_read for parameters since it is not part of the + // interface, and just use the buffer size itself. + CHECK(bytes_to_read == sizeof(PP_FileInfo)); + char* callback_buffer = NULL; + PP_CompletionCallback remote_callback = + MakeRemoteCompletionCallback(rpc->channel, callback_id, bytes_to_read, + &callback_buffer, IsResultPP_OK, + SizeOfPP_FileInfo); + if (NULL == remote_callback.func) + return; + + // callback_buffer has been assigned to a buffer on the heap, the size + // of PP_FileInfo. + PP_FileInfo* file_info = reinterpret_cast<PP_FileInfo*>(callback_buffer); + *pp_error = PPBFileIOInterface()->Query(file_io, file_info, remote_callback); + DebugPrintf("PPB_FileIO::Query: pp_error=%"NACL_PRId32"\n", *pp_error); + CHECK(*pp_error != PP_OK); // Query should not complete synchronously + + *info_bytes = 0; + if (*pp_error != PP_OK_COMPLETIONPENDING) { + DeleteRemoteCallbackInfo(remote_callback); + } + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbFileIORpcServer::PPB_FileIO_Touch( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_io, + double last_access_time, + double last_modified_time, + int32_t callback_id, + int32_t* pp_error) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_CompletionCallback remote_callback = MakeRemoteCompletionCallback( + rpc->channel, + callback_id); + if (NULL == remote_callback.func) + return; + + *pp_error = PPBFileIOInterface()->Touch(file_io, last_access_time, + last_modified_time, remote_callback); + DebugPrintf("PPB_FileIO::Touch: pp_error=%"NACL_PRId32"\n", *pp_error); + CHECK(*pp_error != PP_OK); // Touch should not complete synchronously + + if (*pp_error != PP_OK_COMPLETIONPENDING) + DeleteRemoteCallbackInfo(remote_callback); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbFileIORpcServer::PPB_FileIO_Read( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Resource file_io, + int64_t offset, + int32_t bytes_to_read, + int32_t callback_id, + // outputs + nacl_abi_size_t* buffer_size, + char* buffer, + int32_t* pp_error_or_bytes) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + CHECK(*buffer_size <= + static_cast<nacl_abi_size_t>(std::numeric_limits<int32_t>::max())); + CHECK(*buffer_size == static_cast<nacl_abi_size_t>(bytes_to_read)); + + char* callback_buffer = NULL; + PP_CompletionCallback remote_callback = + MakeRemoteCompletionCallback(rpc->channel, callback_id, bytes_to_read, + &callback_buffer); + if (NULL == remote_callback.func) + return; + + *pp_error_or_bytes = PPBFileIOInterface()->Read( + file_io, + offset, + callback_buffer, + bytes_to_read, + remote_callback); + DebugPrintf("PPB_FileIO::Read: pp_error_or_bytes=%"NACL_PRId32"\n", + *pp_error_or_bytes); + CHECK(*pp_error_or_bytes <= bytes_to_read); + + if (*pp_error_or_bytes > 0) { // Bytes read into |callback_buffer|. + // No callback scheduled. + CHECK(static_cast<nacl_abi_size_t>(*pp_error_or_bytes) <= *buffer_size); + *buffer_size = static_cast<nacl_abi_size_t>(*pp_error_or_bytes); + memcpy(buffer, callback_buffer, *buffer_size); + DeleteRemoteCallbackInfo(remote_callback); + } else if (*pp_error_or_bytes != PP_OK_COMPLETIONPENDING) { // Async error. + // No callback scheduled. + *buffer_size = 0; + DeleteRemoteCallbackInfo(remote_callback); + } else { + // Callback scheduled. + *buffer_size = 0; + } + + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbFileIORpcServer::PPB_FileIO_Write( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_io, + int64_t offset, + nacl_abi_size_t buffer_bytes, char* buffer, + int32_t bytes_to_write, + int32_t callback_id, + int32_t* pp_error_or_bytes) { + // TODO(sanga): Add comments for the parameters. + + CHECK(buffer_bytes <= + static_cast<nacl_abi_size_t>(std::numeric_limits<int32_t>::max())); + CHECK(static_cast<nacl_abi_size_t>(bytes_to_write) <= buffer_bytes); + + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_CompletionCallback remote_callback = MakeRemoteCompletionCallback( + rpc->channel, callback_id); + if (NULL == remote_callback.func) + return; + + *pp_error_or_bytes = PPBFileIOInterface()->Write(file_io, offset, buffer, + bytes_to_write, + remote_callback); + DebugPrintf("PPB_FileIO::Write: pp_error_or_bytes=%"NACL_PRId32"\n", + *pp_error_or_bytes); + + // Bytes must be written asynchronously. + if (*pp_error_or_bytes != PP_OK_COMPLETIONPENDING) { + DeleteRemoteCallbackInfo(remote_callback); + } + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbFileIORpcServer::PPB_FileIO_SetLength( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_io, + int64_t length, + int32_t callback_id, + int32_t* pp_error) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_CompletionCallback remote_callback = MakeRemoteCompletionCallback( + rpc->channel, callback_id); + if (NULL == remote_callback.func) + return; + + *pp_error = PPBFileIOInterface()->SetLength(file_io, length, remote_callback); + DebugPrintf("PPB_FileIO::SetLength: pp_error=%"NACL_PRId32"\n", *pp_error); + CHECK(*pp_error != PP_OK); // SetLength should not complete synchronously + + if (*pp_error != PP_OK_COMPLETIONPENDING) + DeleteRemoteCallbackInfo(remote_callback); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbFileIORpcServer::PPB_FileIO_Flush( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_io, + int32_t callback_id, + int32_t* pp_error) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_CompletionCallback remote_callback = MakeRemoteCompletionCallback( + rpc->channel, callback_id); + if (NULL == remote_callback.func) + return; + + *pp_error = PPBFileIOInterface()->Flush(file_io, remote_callback); + DebugPrintf("PPB_FileIO::Flush: pp_error=%"NACL_PRId32"\n", *pp_error); + CHECK(*pp_error != PP_OK); // Flush should not complete synchronously + + if (*pp_error != PP_OK_COMPLETIONPENDING) + DeleteRemoteCallbackInfo(remote_callback); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbFileIORpcServer::PPB_FileIO_Close( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_io) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_OK; + DebugPrintf("PPB_FileIO::Close: file_io=%"NACL_PRIu32"\n", file_io); + PPBFileIOInterface()->Close(file_io); +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_file_ref_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_file_ref_rpc_server.cc new file mode 100644 index 0000000..3fe8c70 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_file_ref_rpc_server.cc @@ -0,0 +1,213 @@ +// 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_callback.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/ppapi_proxy/object_serialize.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/pp_errors.h" +#include "srpcgen/ppb_rpc.h" + +using ppapi_proxy::DebugPrintf; +using ppapi_proxy::DeleteRemoteCallbackInfo; +using ppapi_proxy::MakeRemoteCompletionCallback; +using ppapi_proxy::PPBFileRefInterface; +using ppapi_proxy::SerializeTo; + +void PpbFileRefRpcServer::PPB_FileRef_Create( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_system, + nacl_abi_size_t path_size, + char* path_bytes, + PP_Resource* resource) { + UNREFERENCED_PARAMETER(path_size); + + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_OK; + + *resource = PPBFileRefInterface()->Create(file_system, path_bytes); + DebugPrintf("PPB_FileRef::Create: resource=%"NACL_PRId32"\n", *resource); +} + +// TODO(sanga): Use a caching resource tracker instead of going over the proxy +// to determine if the given resource is a file ref. +void PpbFileRefRpcServer::PPB_FileRef_IsFileRef( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* pp_success) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_OK; + + *pp_success = PPBFileRefInterface()->IsFileRef(resource); + DebugPrintf("PPB_FileRef::IsFileRef: pp_success=%d\n", *pp_success); +} + +void PpbFileRefRpcServer::PPB_FileRef_GetFileSystemType( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_ref, + int32_t* file_system_type) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_OK; + + *file_system_type = PPBFileRefInterface()->GetFileSystemType(file_ref); + DebugPrintf("PPB_FileRef::GetFileSystemType: file_system_type=%d\n", + file_system_type); +} + +void PpbFileRefRpcServer::PPB_FileRef_GetName( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_ref, + nacl_abi_size_t* name_size, + char* name_bytes) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_Var name = PPBFileRefInterface()->GetName(file_ref); + DebugPrintf("PPB_FileRef::GetName: name.type=%d\n", name.type); + + if (SerializeTo(&name, name_bytes, name_size)) + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbFileRefRpcServer::PPB_FileRef_GetPath( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_ref, + nacl_abi_size_t* path_size, + char* path_bytes) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_Var path = PPBFileRefInterface()->GetPath(file_ref); + DebugPrintf("PPB_FileRef::GetName: path.type=%d\n", path.type); + + if (SerializeTo(&path, path_bytes, path_size)) + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbFileRefRpcServer::PPB_FileRef_GetParent( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_ref, + PP_Resource* parent) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_OK; + + *parent = PPBFileRefInterface()->GetParent(file_ref); + DebugPrintf("PPB_FileRef::GetParent: parent=%"NACL_PRId32"\n", *parent); +} + +void PpbFileRefRpcServer::PPB_FileRef_MakeDirectory( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource directory_ref, + int32_t make_ancestors, + int32_t callback_id, + int32_t* pp_error) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_CompletionCallback remote_callback = MakeRemoteCompletionCallback( + rpc->channel, + callback_id); + if (remote_callback.func == NULL) + return; + + *pp_error = PPBFileRefInterface()->MakeDirectory( + directory_ref, + make_ancestors ? PP_TRUE : PP_FALSE, + remote_callback); + DebugPrintf("PPB_FileRef::MakeDirectory: pp_error=%"NACL_PRId32"\n", + *pp_error); + CHECK(*pp_error != PP_OK); // MakeDirectory does not complete synchronously + + if (*pp_error != PP_OK_COMPLETIONPENDING) + DeleteRemoteCallbackInfo(remote_callback); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbFileRefRpcServer::PPB_FileRef_Touch( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_ref, + double last_access_time, + double last_modified_time, + int32_t callback_id, + int32_t* pp_error) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_CompletionCallback remote_callback = MakeRemoteCompletionCallback( + rpc->channel, + callback_id); + if (remote_callback.func == NULL) + return; + + *pp_error = PPBFileRefInterface()->Touch( + file_ref, + last_access_time, + last_modified_time, + remote_callback); + DebugPrintf("PPB_FileRef::Touch: pp_error=%"NACL_PRId32"\n", *pp_error); + CHECK(*pp_error != PP_OK); // Touch does not complete synchronously + + if (*pp_error != PP_OK_COMPLETIONPENDING) + DeleteRemoteCallbackInfo(remote_callback); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbFileRefRpcServer::PPB_FileRef_Delete( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_ref, + int32_t callback_id, + int32_t* pp_error) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_CompletionCallback remote_callback = MakeRemoteCompletionCallback( + rpc->channel, + callback_id); + if (remote_callback.func == NULL) + return; + + *pp_error = PPBFileRefInterface()->Delete(file_ref, remote_callback); + DebugPrintf("PPB_FileRef::Delete: pp_error=%"NACL_PRId32"\n", *pp_error); + CHECK(*pp_error != PP_OK); // Delete does not complete synchronously + + if (*pp_error != PP_OK_COMPLETIONPENDING) + DeleteRemoteCallbackInfo(remote_callback); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbFileRefRpcServer::PPB_FileRef_Rename( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_ref, + PP_Resource new_file_ref, + int32_t callback_id, + int32_t* pp_error) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_CompletionCallback remote_callback = MakeRemoteCompletionCallback( + rpc->channel, + callback_id); + if (remote_callback.func == NULL) + return; + + *pp_error = PPBFileRefInterface()->Rename(file_ref, new_file_ref, + remote_callback); + DebugPrintf("PPB_FileRef::Rename: pp_error=%"NACL_PRId32"\n", *pp_error); + CHECK(*pp_error != PP_OK); // Rename does not complete synchronously + + if (*pp_error != PP_OK_COMPLETIONPENDING) + DeleteRemoteCallbackInfo(remote_callback); + rpc->result = NACL_SRPC_RESULT_OK; +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_file_system_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_file_system_rpc_server.cc new file mode 100644 index 0000000..c77cac6 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_file_system_rpc_server.cc @@ -0,0 +1,95 @@ +// 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_callback.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" +#include "srpcgen/ppb_rpc.h" + +using ppapi_proxy::DebugPrintf; +using ppapi_proxy::DeleteRemoteCallbackInfo; +using ppapi_proxy::MakeRemoteCompletionCallback; +using ppapi_proxy::PPBFileSystemInterface; + +void PpbFileSystemRpcServer::PPB_FileSystem_Create( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t file_system_type, + PP_Resource* resource) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + *resource = PPBFileSystemInterface()->Create( + instance, + static_cast<PP_FileSystemType>(file_system_type)); + DebugPrintf("PPB_FileSystem::Create: resource=%"NACL_PRIu32"\n", + *resource); + + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbFileSystemRpcServer::PPB_FileSystem_IsFileSystem( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* success) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + *success = PPBFileSystemInterface()->IsFileSystem(resource); + + DebugPrintf("PPB_FileSystem::IsFileSystem: resource=%"NACL_PRIu32"\n", + resource); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbFileSystemRpcServer::PPB_FileSystem_Open( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_system, + int64_t expected_size, + int32_t callback_id, + int32_t* pp_error) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + DebugPrintf("PPB_FileSystem::Open: file_system=%"NACL_PRIu32"\n", + file_system); + + PP_CompletionCallback remote_callback = MakeRemoteCompletionCallback( + rpc->channel, + callback_id); + + if (remote_callback.func == NULL) + return; + + *pp_error = PPBFileSystemInterface()->Open(file_system, expected_size, + remote_callback); + + DebugPrintf("PPB_FileSystem::Open: pp_error=%"NACL_PRId32"\n", *pp_error); + + if (*pp_error != PP_OK_COMPLETIONPENDING) + DeleteRemoteCallbackInfo(remote_callback); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbFileSystemRpcServer::PPB_FileSystem_GetType( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_system, + int32_t* type) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + DebugPrintf("PPB_FileSystem::GetType: file_system=%"NACL_PRIu32"\n", + file_system); + + *type = PPBFileSystemInterface()->GetType(file_system); + + DebugPrintf("PPB_FileSystem::GetType: type=%"NACL_PRId32"\n", *type); + + rpc->result = NACL_SRPC_RESULT_OK; +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_find_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_find_rpc_server.cc new file mode 100644 index 0000000..a4794d98 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_find_rpc_server.cc @@ -0,0 +1,55 @@ +// 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. +// +// SRPC-abstraction wrappers around PPB_Find_Dev functions. + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "native_client/src/trusted/desc/nacl_desc_wrapper.h" +#include "ppapi/c/dev/ppb_find_dev.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_point.h" +#include "ppapi/c/ppb_image_data.h" +#include "srpcgen/ppb_rpc.h" + +using ppapi_proxy::DebugPrintf; +using ppapi_proxy::PPBFindInterface; + +void PpbFindRpcServer::PPB_Find_NumberOfFindResultsChanged( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t total, + int32_t final_result) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PPBFindInterface()->NumberOfFindResultsChanged( + instance, + total, + final_result ? PP_TRUE : PP_FALSE); + + DebugPrintf("PPB_Find::NumberOfFindResultsChanged: " + "instance=%"NACL_PRIu32"\n", instance); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbFindRpcServer::PPB_Find_SelectedFindResultChanged( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t index) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PPBFindInterface()->SelectedFindResultChanged(instance, index); + + DebugPrintf("PPB_Find::SelectedFindResultChanged: " + "instance=%"NACL_PRIu32"\n", instance); + rpc->result = NACL_SRPC_RESULT_OK; +} + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_font_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_font_rpc_server.cc new file mode 100644 index 0000000..35b834f --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_font_rpc_server.cc @@ -0,0 +1,230 @@ +// 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. +// +// SRPC-abstraction wrappers around PPB_Font_Dev functions. + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/ppapi_proxy/object_serialize.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "native_client/src/trusted/desc/nacl_desc_wrapper.h" +#include "ppapi/c/dev/ppb_font_dev.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_point.h" +#include "ppapi/c/pp_rect.h" +#include "ppapi/c/ppb_image_data.h" +#include "srpcgen/ppb_rpc.h" + +using ppapi_proxy::DebugPrintf; +using ppapi_proxy::SerializeTo; +using ppapi_proxy::DeserializeTo; +using ppapi_proxy::PPBFontInterface; + +void PpbFontRpcServer::PPB_Font_GetFontFamilies( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Instance instance, + // outputs + nacl_abi_size_t* font_families_size, char* font_families_bytes) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_Var font_families = PPBFontInterface()->GetFontFamilies(instance); + DebugPrintf("PPB_Font::GetFontFamilies: type=%d\n", + font_families.type); + + if (!SerializeTo( + &font_families, font_families_bytes, font_families_size)) + return; + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbFontRpcServer::PPB_Font_Create( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + nacl_abi_size_t description_size, char* description, + nacl_abi_size_t face_size, char* face, + PP_Resource* font) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + if (description_size != sizeof(struct PP_FontDescription_Dev)) + return; + struct PP_FontDescription_Dev* pp_description = + reinterpret_cast<struct PP_FontDescription_Dev*>(description); + if (!DeserializeTo( + rpc->channel, face, face_size, 1, &pp_description->face)) { + return; + } + *font = PPBFontInterface()->Create(instance, pp_description); + + DebugPrintf("PPB_Font_Dev::Create: font=%"NACL_PRIu32"\n", *font); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbFontRpcServer::PPB_Font_IsFont( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* is_font) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_Bool pp_is_font = PPBFontInterface()->IsFont(resource); + *is_font = (pp_is_font == PP_TRUE); + + DebugPrintf("PPB_Font_Dev::IsFont: is_font=%"NACL_PRId32"\n", *is_font); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbFontRpcServer::PPB_Font_Describe( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource font, + nacl_abi_size_t* description_size, char* description, + nacl_abi_size_t* face_size, char* face, + nacl_abi_size_t* metrics_size, char* metrics, + int32_t* success) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + if (*description_size != sizeof(struct PP_FontDescription_Dev)) + return; + if (*metrics_size != sizeof(struct PP_FontMetrics_Dev)) + return; + struct PP_FontDescription_Dev* pp_description = + reinterpret_cast<struct PP_FontDescription_Dev*>(description); + pp_description->face= PP_MakeUndefined(); + struct PP_FontMetrics_Dev* pp_metrics = + reinterpret_cast<struct PP_FontMetrics_Dev*>(metrics); + PP_Bool pp_success = PPBFontInterface()->Describe(font, + pp_description, + pp_metrics); + if (!SerializeTo(&pp_description->face, face, face_size)) + return; + *success = (pp_success == PP_TRUE); + + DebugPrintf("PPB_Font_Dev::Describe: success=%"NACL_PRIu32"\n", *success); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbFontRpcServer::PPB_Font_DrawTextAt( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource font, + PP_Resource image_data, + nacl_abi_size_t text_run_size, char* text_run, + nacl_abi_size_t text_size, char* text, + nacl_abi_size_t position_size, char* position, + int32_t color, + nacl_abi_size_t clip_size, char* clip, + int32_t image_data_is_opaque, + int32_t* success) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + if (text_run_size != sizeof(struct PP_TextRun_Dev)) + return; + if (position_size != sizeof(struct PP_Point)) + return; + if (clip_size != sizeof(struct PP_Rect)) + return; + struct PP_TextRun_Dev* pp_text_run = + reinterpret_cast<struct PP_TextRun_Dev*>(text_run); + if (!DeserializeTo(rpc->channel, text, text_size, 1, &pp_text_run->text)) + return; + struct PP_Point* pp_position = + reinterpret_cast<struct PP_Point*>(position); + struct PP_Rect* pp_clip = + reinterpret_cast<struct PP_Rect*>(clip); + PP_Bool pp_image_data_is_opaque = image_data_is_opaque ? PP_TRUE : PP_FALSE; + PP_Bool pp_success = PPBFontInterface()->DrawTextAt(font, + image_data, + pp_text_run, + pp_position, + color, + pp_clip, + pp_image_data_is_opaque); + *success = (pp_success == PP_TRUE); + DebugPrintf("PPB_Font_Dev::DrawTextAt: success=%"NACL_PRIu32"\n", *success); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbFontRpcServer::PPB_Font_MeasureText( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource font, + nacl_abi_size_t text_run_size, char* text_run, + nacl_abi_size_t text_size, char* text, + int32_t* width) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + if (text_run_size != sizeof(struct PP_TextRun_Dev)) + return; + struct PP_TextRun_Dev* pp_text_run = + reinterpret_cast<struct PP_TextRun_Dev*>(text_run); + if (!DeserializeTo(rpc->channel, text, text_size, 1, &pp_text_run->text)) + return; + *width = PPBFontInterface()->MeasureText(font, pp_text_run); + + DebugPrintf("PPB_Font_Dev::MeasureText: width=%"NACL_PRIu32"\n", *width); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbFontRpcServer::PPB_Font_CharacterOffsetForPixel( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource font, + nacl_abi_size_t text_run_size, char* text_run, + nacl_abi_size_t text_size, char* text, + int32_t pixel_position, + int32_t* offset) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + if (text_run_size != sizeof(struct PP_TextRun_Dev)) + return; + struct PP_TextRun_Dev* pp_text_run = + reinterpret_cast<struct PP_TextRun_Dev*>(text_run); + if (!DeserializeTo(rpc->channel, text, text_size, 1, &pp_text_run->text)) + return; + *offset = PPBFontInterface()->CharacterOffsetForPixel(font, + pp_text_run, + pixel_position); + + DebugPrintf("PPB_Font_Dev::CharacterOffsetForPixel: " + "offset=%"NACL_PRId32"\n", *offset); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbFontRpcServer::PPB_Font_PixelOffsetForCharacter( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource font, + nacl_abi_size_t text_run_size, char* text_run, + nacl_abi_size_t text_size, char* text, + int32_t char_offset, + int32_t* offset) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + if (text_run_size != sizeof(struct PP_TextRun_Dev)) + return; + struct PP_TextRun_Dev* pp_text_run = + reinterpret_cast<struct PP_TextRun_Dev*>(text_run); + if (!DeserializeTo(rpc->channel, text, text_size, 1, &pp_text_run->text)) + return; + *offset = PPBFontInterface()->PixelOffsetForCharacter(font, + pp_text_run, + char_offset); + DebugPrintf("PPB_Font_Dev::PixelOffsetForCharacter: " + "offset=%"NACL_PRId32"\n", *offset); + rpc->result = NACL_SRPC_RESULT_OK; +} + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_graphics_2d_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_graphics_2d_rpc_server.cc new file mode 100644 index 0000000..d2cbd44 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_graphics_2d_rpc_server.cc @@ -0,0 +1,180 @@ +// 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. +// +// SRPC-abstraction wrappers around PPB_Graphics2D functions. + +#include "native_client/src/include/portability.h" +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/shared/ppapi_proxy/browser_callback.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_point.h" +#include "ppapi/c/pp_rect.h" +#include "ppapi/c/pp_size.h" +#include "ppapi/c/ppb_graphics_2d.h" +#include "srpcgen/ppb_rpc.h" + +using ppapi_proxy::DebugPrintf; +using ppapi_proxy::PPBGraphics2DInterface; + +namespace { + +// Two functions below use a NULL PP_Rect pointer to indicate that the +// entire image should be updated. +const struct PP_Rect* kEntireImage = NULL; + +} // namespace + +void PpbGraphics2DRpcServer::PPB_Graphics2D_Create(NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + nacl_abi_size_t size_bytes, + char* size, + int32_t is_always_opaque, + PP_Resource* resource) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + *resource = ppapi_proxy::kInvalidResourceId; + if (size_bytes != sizeof(struct PP_Size)) { + return; + } + *resource = PPBGraphics2DInterface()->Create( + instance, + const_cast<const struct PP_Size*>( + reinterpret_cast<struct PP_Size*>(size)), + (is_always_opaque ? PP_TRUE : PP_FALSE)); + DebugPrintf("PPB_Graphics2D::Create: resource=%"NACL_PRIu32"\n", *resource); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbGraphics2DRpcServer::PPB_Graphics2D_IsGraphics2D(NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* success) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + *success = 0; + PP_Bool pp_success = PPBGraphics2DInterface()->IsGraphics2D(resource); + *success = (pp_success == PP_TRUE); + DebugPrintf("PPB_Graphics2D::IsGraphics2D: pp_success=%d\n", pp_success); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbGraphics2DRpcServer::PPB_Graphics2D_Describe( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource graphics_2d, + nacl_abi_size_t* size_bytes, + char* size, + int32_t* is_always_opaque, + int32_t* success) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + *success = 0; + if (*size_bytes != sizeof(struct PP_Size)) { + return; + } + PP_Bool is_opaque; + PP_Bool pp_success = PPBGraphics2DInterface()->Describe( + graphics_2d, reinterpret_cast<struct PP_Size*>(size), &is_opaque); + *is_always_opaque = (is_opaque == PP_TRUE); + *success = (pp_success == PP_TRUE); + DebugPrintf("PPB_Graphics2D::Describe: pp_success=%d\n", pp_success); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbGraphics2DRpcServer::PPB_Graphics2D_PaintImageData( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource graphics_2d, + PP_Resource image, + nacl_abi_size_t top_left_bytes, + char* top_left, + nacl_abi_size_t src_rect_bytes, + char* src_rect) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + if (top_left_bytes != sizeof(struct PP_Point)) { // NULL top_left is invalid. + return; + } + const struct PP_Rect* rect = kEntireImage; + if (src_rect_bytes == sizeof(struct PP_Rect)) { + rect = const_cast<const struct PP_Rect*>( + reinterpret_cast<struct PP_Rect*>(src_rect)); + } else if (src_rect_bytes != 0) { + return; + } + PPBGraphics2DInterface()->PaintImageData( + graphics_2d, + image, + const_cast<const struct PP_Point*>( + reinterpret_cast<struct PP_Point*>(top_left)), + rect); + DebugPrintf("PPB_Graphics2D::PaintImageData\n"); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbGraphics2DRpcServer::PPB_Graphics2D_Scroll( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource graphics_2d, + nacl_abi_size_t clip_rect_bytes, + char* clip_rect, + nacl_abi_size_t amount_bytes, + char* amount) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + if (amount_bytes != sizeof(struct PP_Point)) { // NULL amount is invalid. + return; + } + const struct PP_Rect* rect = kEntireImage; + if (clip_rect_bytes == sizeof(struct PP_Rect)) { + rect = const_cast<const struct PP_Rect*>( + reinterpret_cast<struct PP_Rect*>(clip_rect)); + } else if (clip_rect_bytes != 0) { + return; + } + PPBGraphics2DInterface()->Scroll( + graphics_2d, + rect, + const_cast<const struct PP_Point*>( + reinterpret_cast<struct PP_Point*>(amount))); + DebugPrintf("PPB_Graphics2D::Scroll\n"); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbGraphics2DRpcServer::PPB_Graphics2D_ReplaceContents( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource graphics_2d, + PP_Resource image) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + PPBGraphics2DInterface()->ReplaceContents(graphics_2d, image); + DebugPrintf("PPB_Graphics2D::ReplaceContents\n"); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbGraphics2DRpcServer::PPB_Graphics2D_Flush( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource graphics_2d, + int32_t callback_id, + int32_t* pp_error) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_CompletionCallback remote_callback = + ppapi_proxy::MakeRemoteCompletionCallback(rpc->channel, callback_id); + if (remote_callback.func == NULL) + return; // Treat this as a generic SRPC error. + + *pp_error = PPBGraphics2DInterface()->Flush(graphics_2d, remote_callback); + if (*pp_error != PP_OK_COMPLETIONPENDING) // Async error. + ppapi_proxy::DeleteRemoteCallbackInfo(remote_callback); + DebugPrintf("PPB_Graphics2D::Flush: pp_error=%"NACL_PRId32"\n", *pp_error); + rpc->result = NACL_SRPC_RESULT_OK; +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_graphics_3d_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_graphics_3d_rpc_server.cc new file mode 100644 index 0000000..ac3ba14 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_graphics_3d_rpc_server.cc @@ -0,0 +1,353 @@ +// 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. +// +// SRPC-abstraction wrappers around PPB_Graphics3D functions. + +#include <limits> + +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/browser_callback.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/ppapi_proxy/object_serialize.h" +#include "native_client/src/shared/ppapi_proxy/plugin_resource.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "native_client/src/trusted/desc/nacl_desc_wrapper.h" +#include "ppapi/c/dev/pp_graphics_3d_dev.h" +#include "ppapi/c/dev/ppb_graphics_3d_dev.h" +#include "ppapi/c/dev/ppb_graphics_3d_trusted_dev.h" +#include "ppapi/c/pp_errors.h" +#include "srpcgen/ppb_rpc.h" + +using ppapi_proxy::DebugPrintf; +using ppapi_proxy::SerializeTo; + +namespace { + +const int32_t kMaxAllowedBufferSize = 16777216; + +/// Check that the attribute list is well formed. +bool ValidateAttribList(nacl_abi_size_t attrib_list_count, + int32_t* attrib_list) { + DebugPrintf("ValidateAttribList: count = %d, ptr_null = %d\n", + static_cast<int>(attrib_list_count), (attrib_list == NULL) ? 1 : 0); + // Zero count lists are ok. + if (attrib_list_count == 0) + return true; + // NULL lists w/ a non-zero count are not allowed. + if (attrib_list == NULL) + return false; + // Must be an odd count, and the last item must be the terminator. + return (attrib_list_count & 1) && + (attrib_list[attrib_list_count - 1] == PP_GRAPHICS3DATTRIB_NONE); +} + +/// Check that the attribute list is well formed, then copy to output. +bool ValidateAndCopyAttribList(nacl_abi_size_t in_attrib_list_count, + int32_t* in_attrib_list, + nacl_abi_size_t* out_attrib_list_count, + int32_t* out_attrib_list) { + + DebugPrintf("ValidateAndCopyAttribList: in_count = %d, in_ptr_null = %d\n", + static_cast<int>(in_attrib_list_count), + (in_attrib_list == NULL) ? 1 : 0); + DebugPrintf(" out_count = %d, out_ptr_null = %d\n", + static_cast<int>(*out_attrib_list_count), + (out_attrib_list == NULL) ? 1 : 0); + + // Attrib lists can both be NULL w/ 0 count. + if ((in_attrib_list == NULL) && (out_attrib_list == NULL)) + return (in_attrib_list_count == 0) && (*out_attrib_list_count == 0); + // Don't allow only one list to be NULL. + if ((in_attrib_list == NULL) || (out_attrib_list == NULL)) + return false; + // Input and output lists must be the same size. + if (in_attrib_list_count != *out_attrib_list_count) + return false; + // Make sure input list is well formed. + if (!ValidateAttribList(in_attrib_list_count, in_attrib_list)) + return false; + // Copy input list to output list. + // Note: attrib lists can be zero sized. + for (nacl_abi_size_t i = 0; i < in_attrib_list_count; ++i) + out_attrib_list[i] = in_attrib_list[i]; + return true; +} + +} // namespace + +//@{ +/// The following methods are SRPC dispatchers for ppapi/c/ppb_graphics_3d.h. + +void PpbGraphics3DRpcServer::PPB_Graphics3D_Create( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + PP_Resource share_context, + nacl_abi_size_t num_attrib_list, int32_t* attrib_list, + PP_Resource* graphics3d_id) { + DebugPrintf("PpbGraphics3DRpcServer::PPB_Graphics3D_Create(...)\n"); + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + if (num_attrib_list == 0) + attrib_list = NULL; + if (!ValidateAttribList(num_attrib_list, attrib_list)) + return; + *graphics3d_id = ppapi_proxy::PPBGraphics3DInterface()->Create( + instance, share_context, attrib_list); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbGraphics3DRpcServer::PPB_Graphics3D_GetAttribs( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource graphics3d_id, + nacl_abi_size_t in_attrib_list_count, int32_t* in_attrib_list, + nacl_abi_size_t* out_attrib_list_count, int32_t* out_attrib_list, + int32_t* pp_error) { + DebugPrintf("PpbGraphics3DRpcServer::PPB_Graphics3D_GetAttrib(...)\n"); + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + if (in_attrib_list_count == 0) + in_attrib_list = NULL; + if (*out_attrib_list_count == 0) + out_attrib_list = NULL; + if (!ValidateAndCopyAttribList(in_attrib_list_count, in_attrib_list, + out_attrib_list_count, out_attrib_list)) + return; + *pp_error = ppapi_proxy::PPBGraphics3DInterface()->GetAttribs( + graphics3d_id, out_attrib_list); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbGraphics3DRpcServer::PPB_Graphics3D_SetAttribs( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource graphics3d_id, + nacl_abi_size_t attrib_list_count, int32_t* attrib_list, + int32_t* pp_error) { + DebugPrintf("PpbGraphics3DRpcServer::PPB_Graphics3D_SetAttrib(...)\n"); + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + if (attrib_list_count == 0) + attrib_list = NULL; + if (!ValidateAttribList(attrib_list_count, attrib_list)) + return; + *pp_error = ppapi_proxy::PPBGraphics3DInterface()->SetAttribs( + graphics3d_id, attrib_list); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbGraphics3DRpcServer::PPB_Graphics3D_ResizeBuffers( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource graphics3d_id, + int32_t width, + int32_t height, + int32_t* pp_error) { + DebugPrintf("PpbGraphics3DRpcServer::PPB_Graphics3D_ResizeBuffers(...)\n"); + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + *pp_error = ppapi_proxy::PPBGraphics3DInterface()->ResizeBuffers( + graphics3d_id, width, height); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbGraphics3DRpcServer::PPB_Graphics3D_SwapBuffers( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource graphics3d_id, + int32_t callback_id, + int32_t* pp_error) { + DebugPrintf("PpbGraphics3DRpcServer::PPB_Graphics3D_SwapBuffers(...)\n"); + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + PP_CompletionCallback remote_callback = + ppapi_proxy::MakeRemoteCompletionCallback(rpc->channel, callback_id); + if (remote_callback.func == NULL) { + DebugPrintf(" PPB_Graphics3D_SwapBuffers() FAILED!\n"); + return; // Treat this as a generic SRPC error. + } + *pp_error = ppapi_proxy::PPBGraphics3DInterface()->SwapBuffers( + graphics3d_id, remote_callback); + if (*pp_error != PP_OK_COMPLETIONPENDING) + ppapi_proxy::DeleteRemoteCallbackInfo(remote_callback); + DebugPrintf(" PPB_Graphics3D_SwapBuffers: pp_error=%"NACL_PRId32"\n", + *pp_error); + rpc->result = NACL_SRPC_RESULT_OK; +} + +//@} + +//@{ +/// The following methods are the SRPC dispatchers for +/// ppapi/c/ppb_graphics_3d_trusted.h. +void PpbGraphics3DRpcServer::PPB_Graphics3DTrusted_CreateRaw( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + PP_Resource share_context, + nacl_abi_size_t attrib_list_size, int32_t* attrib_list, + PP_Resource* resource_id) { + DebugPrintf("PPB_Graphics3DTrusted_CreateRaw: instance: %"NACL_PRIu32"\n", + instance); + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + if (attrib_list_size == 0) + attrib_list = NULL; + if (!ValidateAttribList(attrib_list_size, attrib_list)) + return; + *resource_id = ppapi_proxy::PPBGraphics3DTrustedInterface()->CreateRaw( + instance, share_context, attrib_list); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbGraphics3DRpcServer::PPB_Graphics3DTrusted_InitCommandBuffer( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource_id, + int32_t size, + int32_t* success) { + DebugPrintf("PPB_Graphics3DTrusted_InitCommandBuffer(...) resource_id: %d\n", + resource_id); + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + if ((size > kMaxAllowedBufferSize) || (size < 0)) + return; + *success = ppapi_proxy::PPBGraphics3DTrustedInterface()->InitCommandBuffer( + resource_id, size); + rpc->result = NACL_SRPC_RESULT_OK; +} + + +void PpbGraphics3DRpcServer::PPB_Graphics3DTrusted_GetRingBuffer( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource_id, + NaClSrpcImcDescType* shm_desc, + int32_t* shm_size) { + DebugPrintf("PPB_Graphics3DTrusted_GetRingBuffer\n"); + nacl::DescWrapperFactory factory; + nacl::scoped_ptr<nacl::DescWrapper> desc_wrapper; + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + int native_handle = 0; + uint32_t native_size = 0; + ppapi_proxy::PPBGraphics3DTrustedInterface()->GetRingBuffer( + resource_id, &native_handle, &native_size); + desc_wrapper.reset(factory.ImportShmHandle( + (NaClHandle)native_handle, native_size)); + *shm_desc = desc_wrapper->desc(); + *shm_size = native_size; + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbGraphics3DRpcServer::PPB_Graphics3DTrusted_GetState( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource_id, + nacl_abi_size_t* state_size, char* state) { + DebugPrintf("PPB_Graphics3DTrusted_GetState\n"); + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + if (*state_size != sizeof(PP_Graphics3DTrustedState)) + return; + PP_Graphics3DTrustedState trusted_state = + ppapi_proxy::PPBGraphics3DTrustedInterface()->GetState(resource_id); + *reinterpret_cast<PP_Graphics3DTrustedState*>(state) = trusted_state; + *state_size = sizeof(trusted_state); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbGraphics3DRpcServer::PPB_Graphics3DTrusted_Flush( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource_id, + int32_t put_offset) { + DebugPrintf("PPB_Graphics3DTrusted_Flush(id: %d, put_offset: %d\n", + resource_id, put_offset); + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + ppapi_proxy::PPBGraphics3DTrustedInterface()->Flush(resource_id, put_offset); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbGraphics3DRpcServer::PPB_Graphics3DTrusted_FlushSync( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource_id, + int32_t put_offset, + nacl_abi_size_t* state_size, char* state) { + DebugPrintf("PPB_Graphics3DTrusted_FlushSync\n"); + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + if (*state_size != sizeof(PP_Graphics3DTrustedState)) + return; + PP_Graphics3DTrustedState trusted_state = + ppapi_proxy::PPBGraphics3DTrustedInterface()->FlushSync(resource_id, + put_offset); + *reinterpret_cast<PP_Graphics3DTrustedState*>(state) = trusted_state; + *state_size = sizeof(trusted_state); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbGraphics3DRpcServer::PPB_Graphics3DTrusted_CreateTransferBuffer( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource_id, + int32_t size, + int32_t id_request, + int32_t* id) { + UNREFERENCED_PARAMETER(id_request); + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + DebugPrintf("PPB_Graphics3DTrusted_CreateTransferBuffer\n"); + if ((size > kMaxAllowedBufferSize) || (size < 0)) + return; + *id = ppapi_proxy::PPBGraphics3DTrustedInterface()->CreateTransferBuffer( + resource_id, size); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbGraphics3DRpcServer::PPB_Graphics3DTrusted_DestroyTransferBuffer( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource_id, + int32_t id) { + DebugPrintf("PPB_Graphics3DTrusted_DestroyTransferBuffer\n"); + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + ppapi_proxy::PPBGraphics3DTrustedInterface()->DestroyTransferBuffer( + resource_id, id); + rpc->result = NACL_SRPC_RESULT_OK; + +} + +void PpbGraphics3DRpcServer::PPB_Graphics3DTrusted_GetTransferBuffer( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource_id, + int32_t id, + NaClSrpcImcDescType* shm_desc, + int32_t* shm_size) { + DebugPrintf("PPB_Graphics3DTrusted_GetTransferBuffer\n"); + nacl::DescWrapperFactory factory; + nacl::scoped_ptr<nacl::DescWrapper> desc_wrapper; + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + int native_handle = 0; + uint32_t native_size = 0; + ppapi_proxy::PPBGraphics3DTrustedInterface()-> + GetTransferBuffer(resource_id, id, &native_handle, &native_size); + desc_wrapper.reset(factory.ImportShmHandle( + (NaClHandle)native_handle, native_size)); + *shm_desc = desc_wrapper->desc(); + *shm_size = native_size; + rpc->result = NACL_SRPC_RESULT_OK; + +} + +//@} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_image_data_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_image_data_rpc_server.cc new file mode 100644 index 0000000..3549b0f --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_image_data_rpc_server.cc @@ -0,0 +1,169 @@ +// Copyright (c) 2010 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. +// +// SRPC-abstraction wrappers around PPB_ImageData functions. + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "native_client/src/trusted/desc/nacl_desc_wrapper.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_point.h" +#include "ppapi/c/pp_rect.h" +#include "ppapi/c/pp_size.h" +#include "ppapi/c/ppb_image_data.h" +#include "ppapi/c/trusted/ppb_image_data_trusted.h" +#include "srpcgen/ppb_rpc.h" + + +using ppapi_proxy::DebugPrintf; + +void PpbImageDataRpcServer::PPB_ImageData_GetNativeImageDataFormat( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + int32_t* format) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + PP_ImageDataFormat pp_format = + ppapi_proxy::PPBImageDataInterface()->GetNativeImageDataFormat(); + *format = static_cast<int32_t>(pp_format); + DebugPrintf("PPB_ImageData::GetNativeImageDataFormat: " + "format=%"NACL_PRId32"\n", *format); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbImageDataRpcServer::PPB_ImageData_IsImageDataFormatSupported( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + int32_t format, + int32_t* success) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + PP_Bool pp_success = + ppapi_proxy::PPBImageDataInterface()->IsImageDataFormatSupported( + static_cast<PP_ImageDataFormat>(format)); + *success = (pp_success == PP_TRUE); + DebugPrintf("PPB_ImageData::IsImageDataFormatSupported: " + "format=%"NACL_PRId32", success=%"NACL_PRId32"\n", + format, *success); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbImageDataRpcServer::PPB_ImageData_Create( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t format, + nacl_abi_size_t size_bytes, char* size, + int32_t init_to_zero, + PP_Resource* resource) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + if (size_bytes != sizeof(struct PP_Size)) { + return; + } + PP_Size pp_size = *(reinterpret_cast<struct PP_Size*>(size)); + *resource = ppapi_proxy::PPBImageDataInterface()->Create( + instance, + static_cast<PP_ImageDataFormat>(format), + &pp_size, + (init_to_zero ? PP_TRUE : PP_FALSE)); + DebugPrintf("PPB_ImageData::Create: format=%"NACL_PRId32", " + "size=(%"NACL_PRId32", %"NACL_PRId32"), " + "init_to_zero=%"NACL_PRId32", " + "resource=%"NACL_PRIu32"\n", + format, pp_size.width, pp_size.height, + init_to_zero, *resource); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbImageDataRpcServer::PPB_ImageData_IsImageData( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* success) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + PP_Bool pp_success = + ppapi_proxy::PPBImageDataInterface()->IsImageData(resource); + *success = (pp_success == PP_TRUE); + DebugPrintf("PPB_ImageData::IsImageData: resource=%"NACL_PRIu32", " + "success=%"NACL_PRId32"\n", resource, *success); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbImageDataRpcServer::PPB_ImageData_Describe( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + nacl_abi_size_t* desc_bytes, + char* desc, + NaClSrpcImcDescType* shm, + int32_t* shm_size, + int32_t* success) { + nacl::DescWrapperFactory factory; + nacl::scoped_ptr<nacl::DescWrapper> desc_wrapper(factory.MakeInvalid()); + // IMPORTANT! + // Make sure that the runner is destroyed before DescWrapper! + // NaclDescs are refcounted. When the DescWrapper is destructed, it decreases + // the refcount, and causes the Desc to be freed. The closure runner will send + // the response in the destructor and segfault when trying to process a freed + // Desc. + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + if (*desc_bytes != sizeof(struct PP_ImageDataDesc)) { + return; + } + *shm = desc_wrapper->desc(); + *shm_size = -1; + *success = PP_FALSE; + PP_Bool pp_success = + ppapi_proxy::PPBImageDataInterface()->Describe( + resource, reinterpret_cast<struct PP_ImageDataDesc*>(desc)); + if (pp_success == PP_TRUE) { + int native_handle = 0; + uint32_t native_size = 0; + if (ppapi_proxy::PPBImageDataTrustedInterface()->GetSharedMemory( + static_cast<PP_Resource>(resource), + &native_handle, + &native_size) == PP_OK) { + +#if NACL_LINUX + desc_wrapper.reset(factory.ImportSysvShm(native_handle, native_size)); + *shm = desc_wrapper->desc(); + *shm_size = native_size; + *success = PP_TRUE; +#elif NACL_WINDOWS + HANDLE dup_handle; + if (DuplicateHandle(GetCurrentProcess(), + reinterpret_cast<NaClHandle>(native_handle), + GetCurrentProcess(), + &dup_handle, + 0, + FALSE, + DUPLICATE_SAME_ACCESS)) { + desc_wrapper.reset(factory.ImportShmHandle(dup_handle, native_size)); + *shm = desc_wrapper->desc(); + *shm_size = native_size; + *success = PP_TRUE; + } +#else + int dup_handle = dup(static_cast<int>(native_handle)); + if (dup_handle >= 0) { + desc_wrapper.reset(factory.ImportShmHandle(dup_handle, native_size)); + *shm = desc_wrapper->desc(); + *shm_size = native_size; + *success = PP_TRUE; + } +#endif + } + } + DebugPrintf("PPB_ImageData::Describe: resource=%"NACL_PRIu32", " + "success=%"NACL_PRId32"\n", resource, *success); + rpc->result = NACL_SRPC_RESULT_OK; +} + +// Map and Unmap are purely plugin-side methods, just using mmap/munmap. diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_input_event_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_input_event_rpc_server.cc new file mode 100644 index 0000000..8d21cd7 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_input_event_rpc_server.cc @@ -0,0 +1,184 @@ +// 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. +// +// SRPC-abstraction wrappers around PPB_InputEvent functions. + +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/ppapi_proxy/browser_ppp_input_event.h" +#include "native_client/src/shared/ppapi_proxy/object_serialize.h" +#include "native_client/src/shared/ppapi_proxy/trusted/srpcgen/ppb_rpc.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/ppb_input_event.h" + + +using ppapi_proxy::DebugPrintf; +using ppapi_proxy::DeserializeTo; + +void PpbInputEventRpcServer::PPB_InputEvent_RequestInputEvents( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t event_classes, + int32_t filtering, + int32_t* success) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + *success = PP_ERROR_FAILED; + DebugPrintf("PPB_InputEvent::RequestInputEvents: instance=%"NACL_PRIu32", " + "event_classes=%"NACL_PRIu32", filtering=%"NACL_PRId32"\n", + instance, static_cast<uint32_t>(event_classes), filtering); + const PPB_InputEvent* input_event_if = ppapi_proxy::PPBInputEventInterface(); + if (!input_event_if) { + *success = PP_ERROR_NOTSUPPORTED; + DebugPrintf("PPB_InputEvent::RequestInputEvents: success=%"NACL_PRId32"\n", + *success); + return; + } + if (filtering) { + *success = input_event_if->RequestFilteringInputEvents( + instance, + static_cast<uint32_t>(event_classes)); + } else { + *success = input_event_if->RequestInputEvents( + instance, + static_cast<uint32_t>(event_classes)); + } + DebugPrintf("PPB_InputEvent::RequestInputEvents: success=%"NACL_PRId32"\n", + *success); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbInputEventRpcServer::PPB_InputEvent_ClearInputEventRequest( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t event_classes) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + DebugPrintf("PPB_InputEvent::ClearInputEventRequest: instance=%"NACL_PRIu32 + ", event_classes=%"NACL_PRIu32"\n", + instance, static_cast<uint32_t>(event_classes)); + const PPB_InputEvent* input_event_if = ppapi_proxy::PPBInputEventInterface(); + if (!input_event_if) { + return; + } + input_event_if->ClearInputEventRequest(instance, + static_cast<uint32_t>(event_classes)); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbInputEventRpcServer::PPB_InputEvent_CreateMouseInputEvent( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t type, // PP_InputEvent_Type + double time_stamp, // PP_TimeTicks + int32_t modifiers, // uint32_t + int32_t mouse_button, // PP_InputEvent_MouseButton + int32_t position_x, // PP_Point.x + int32_t position_y, // PP_Point.y + int32_t click_count, + PP_Resource* resource_id) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + *resource_id = 0; + // TODO(dmichael): Add DebugPrintf. + const PPB_MouseInputEvent* input_event_if = + ppapi_proxy::PPBMouseInputEventInterface(); + if (!input_event_if) { + return; + } + PP_Point mouse_position = { position_x, position_y }; + *resource_id = input_event_if->Create( + instance, + static_cast<PP_InputEvent_Type>(type), + static_cast<PP_TimeTicks>(time_stamp), + static_cast<uint32_t>(modifiers), + static_cast<PP_InputEvent_MouseButton>(mouse_button), + &mouse_position, + click_count); + DebugPrintf("PPB_InputEvent::CreateMouseInputEvent: resource_id=" + "%"NACL_PRId32"\n", + *resource_id); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbInputEventRpcServer::PPB_InputEvent_CreateKeyboardInputEvent( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t type, // PP_InputEvent_Type + double time_stamp, // PP_TimeTicks + int32_t modifiers, // uint32_t + int32_t key_code, + nacl_abi_size_t character_size, + char* character_bytes, + PP_Resource* resource_id) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + *resource_id = 0; + // TODO(dmichael): Add DebugPrintf. + const PPB_KeyboardInputEvent* input_event_if = + ppapi_proxy::PPBKeyboardInputEventInterface(); + if (!input_event_if) { + return; + } + PP_Var character_text; + if (!DeserializeTo(rpc->channel, character_bytes, character_size, 1, + &character_text)) { + return; + } + + *resource_id = input_event_if->Create(instance, + static_cast<PP_InputEvent_Type>(type), + static_cast<PP_TimeTicks>(time_stamp), + static_cast<uint32_t>(modifiers), + key_code, + character_text); + DebugPrintf("PPB_InputEvent::CreateKeyboardInputEvent: resource_id=" + "%"NACL_PRId32"\n", + *resource_id); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbInputEventRpcServer::PPB_InputEvent_CreateWheelInputEvent( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + double time_stamp, // PP_TimeTicks + int32_t modifiers, // uint32_t + double delta_x, // PP_FloatPoint.x + double delta_y, // PP_FloatPoint.y + double ticks_x, // PP_FloatPoint.x + double ticks_y, // PP_FloatPoint.y + int32_t scroll_by_page, // PP_Bool + PP_Resource* resource_id) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + *resource_id = 0; + // TODO(dmichael): Add DebugPrintf. + const PPB_WheelInputEvent* input_event_if = + ppapi_proxy::PPBWheelInputEventInterface(); + if (!input_event_if) { + return; + } + PP_FloatPoint wheel_delta = { static_cast<float>(delta_x), + static_cast<float>(delta_y) }; + PP_FloatPoint wheel_ticks = { static_cast<float>(ticks_x), + static_cast<float>(ticks_y) }; + *resource_id = input_event_if->Create( + instance, + static_cast<PP_TimeTicks>(time_stamp), + static_cast<uint32_t>(modifiers), + &wheel_delta, + &wheel_ticks, + static_cast<PP_Bool>(scroll_by_page)); + DebugPrintf("PPB_InputEvent::CreateWheelInputEvent: resource_id=" + "%"NACL_PRId32"\n", + *resource_id); + rpc->result = NACL_SRPC_RESULT_OK; +} + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_instance_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_instance_rpc_server.cc new file mode 100644 index 0000000..83a30e1 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_instance_rpc_server.cc @@ -0,0 +1,46 @@ +// 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. +// +// SRPC-abstraction wrappers around PPB_Instance functions. + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "srpcgen/ppb_rpc.h" + +void PpbInstanceRpcServer::PPB_Instance_BindGraphics( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Instance instance, + PP_Resource graphics_device, + // outputs + int32_t* success) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_Bool pp_success = + ppapi_proxy::PPBInstanceInterface()->BindGraphics( + instance, + graphics_device); + *success = (pp_success == PP_TRUE); + + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbInstanceRpcServer::PPB_Instance_IsFullFrame( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Instance instance, + // outputs + int32_t* is_full_frame) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_Bool pp_is_full_frame = + ppapi_proxy::PPBInstanceInterface()->IsFullFrame(instance); + *is_full_frame = (pp_is_full_frame == PP_TRUE); + + rpc->result = NACL_SRPC_RESULT_OK; +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_messaging_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_messaging_rpc_server.cc new file mode 100644 index 0000000..136c8c7 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_messaging_rpc_server.cc @@ -0,0 +1,38 @@ +// 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_globals.h" +#include "native_client/src/shared/ppapi_proxy/object_serialize.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "srpcgen/ppb_rpc.h" + +// This is here due to a Windows API collision. +#ifdef PostMessage +#undef PostMessage +#endif + +using ppapi_proxy::PPBMessagingInterface; +using ppapi_proxy::DebugPrintf; +using ppapi_proxy::DeserializeTo; + +void PpbMessagingRpcServer::PPB_Messaging_PostMessage( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + nacl_abi_size_t message_size, + char* message_bytes) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_Var message; + if (!DeserializeTo(rpc->channel, message_bytes, message_size, 1, &message)) + return; + + PPBMessagingInterface()->PostMessage(instance, message); + DebugPrintf("PPB_Messaging::PostMessage: instance=%"NACL_PRIu32"\n", + instance); + + rpc->result = NACL_SRPC_RESULT_OK; +} + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_pdf_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_pdf_rpc_server.cc new file mode 100644 index 0000000..90baec5 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_pdf_rpc_server.cc @@ -0,0 +1,254 @@ +// 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. +// +// SRPC-abstraction wrappers around PPB_PDF functions. + +#include <stdlib.h> +#include <string.h> +#include <algorithm> + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/ppapi_proxy/object_serialize.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "native_client/src/trusted/desc/nacl_desc_wrapper.h" +#include "ppapi/c/dev/ppb_memory_dev.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_rect.h" +#include "ppapi/c/ppb_image_data.h" +#include "ppapi/c/private/ppb_pdf.h" +#include "srpcgen/ppb_rpc.h" + +using ppapi_proxy::DebugPrintf; +using ppapi_proxy::PPBCoreInterface; +using ppapi_proxy::PPBPDFInterface; +using ppapi_proxy::SerializeTo; +using ppapi_proxy::DeserializeTo; + +const nacl_abi_size_t kPpbPrivateFindResultBytes = + static_cast<nacl_abi_size_t>(sizeof(PP_PrivateFindResult)); +// Limit the maximum result buffer size. +const nacl_abi_size_t kMaxFindResultsBytes = 65536; +const int32_t kMaxFindResults = + kMaxFindResultsBytes / kPpbPrivateFindResultBytes; + +void PpbPdfRpcServer::PPB_PDF_GetLocalizedString( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t string_id, + nacl_abi_size_t* string_size, char* string) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_Var pp_string = + PPBPDFInterface()->GetLocalizedString( + instance, + static_cast<PP_ResourceString>(string_id)); + + DebugPrintf("PPB_PDF::GetLocalizedString: " + "string_id=%"NACL_PRId32"\n", string_id); + if (!SerializeTo(&pp_string, string, string_size)) + return; + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbPdfRpcServer::PPB_PDF_GetResourceImage( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t image_id, + PP_Resource* resource) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + *resource = PPBPDFInterface()->GetResourceImage( + instance, + static_cast<PP_ResourceImage>(image_id)); + + DebugPrintf("PPB_PDF::GetResourceImage: image_id=%"NACL_PRId32"\n", image_id); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbPdfRpcServer::PPB_PDF_GetFontFileWithFallback( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + nacl_abi_size_t description_size, char* description, + nacl_abi_size_t face_size, char* face, + int32_t charset, + PP_Resource* resource) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + UNREFERENCED_PARAMETER(instance); + UNREFERENCED_PARAMETER(description_size); + UNREFERENCED_PARAMETER(description); + UNREFERENCED_PARAMETER(face_size); + UNREFERENCED_PARAMETER(face); + UNREFERENCED_PARAMETER(charset); + + *resource = ppapi_proxy::kInvalidResourceId; + DebugPrintf("PPB_PDF::GetFontFileWithFallback: not implemented.\n"); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbPdfRpcServer::PPB_PDF_GetFontTableForPrivateFontFile( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource font_file, + int32_t table, + nacl_abi_size_t* output_size, char* output, + int32_t* success) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + UNREFERENCED_PARAMETER(font_file); + UNREFERENCED_PARAMETER(table); + UNREFERENCED_PARAMETER(output); + + *output_size = 0; + *success = 0; + + DebugPrintf("PPB_PDF::GetFontTableForPrivateFontFile: not implemented.\n"); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbPdfRpcServer::PPB_PDF_SearchString( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + nacl_abi_size_t string_size, char* string, + nacl_abi_size_t term_size, char* term, + int32_t case_sensitive, + nacl_abi_size_t* results_size, char* results, + int32_t* count) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + UNREFERENCED_PARAMETER(string_size); + UNREFERENCED_PARAMETER(term_size); + struct PP_PrivateFindResult* pp_results = NULL; + int pp_result_count = 0; + PPBPDFInterface()->SearchString( + instance, + reinterpret_cast<unsigned short*>(string), + reinterpret_cast<unsigned short*>(term), + case_sensitive ? PP_TRUE : PP_FALSE, + &pp_results, + &pp_result_count); + pp_result_count = std::min(pp_result_count, kMaxFindResults); + *results_size = std::min(*results_size, + pp_result_count * kPpbPrivateFindResultBytes); + if (pp_results) { + memcpy(results, pp_results, *results_size); + // On Windows, the call to |free| must be made in the renderer's .exe, + // not in the .dll code. That can cause a crash in some configurations. + ppapi_proxy::PPBMemoryInterface()->MemFree(pp_results); + } + *count = static_cast<int32_t>(pp_result_count); + + DebugPrintf("PPB_PDF::SearchString: count=%"NACL_PRId32"\n", *count); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbPdfRpcServer::PPB_PDF_DidStartLoading( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PPBPDFInterface()->DidStartLoading(instance); + + DebugPrintf("PPB_PDF::DidStartLoading: instance=%"NACL_PRId32"\n", instance); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbPdfRpcServer::PPB_PDF_DidStopLoading( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PPBPDFInterface()->DidStopLoading(instance); + + DebugPrintf("PPB_PDF::DidStopLoading: instance=%"NACL_PRId32"\n", instance); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbPdfRpcServer::PPB_PDF_SetContentRestriction( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t restrictions) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PPBPDFInterface()->SetContentRestriction(instance, restrictions); + + DebugPrintf("PPB_PDF::SetContentRestriction: instance=%"NACL_PRId32"\n", + instance); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbPdfRpcServer::PPB_PDF_HistogramPDFPageCount( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + int32_t count) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PPBPDFInterface()->HistogramPDFPageCount(count); + + DebugPrintf("PPB_PDF::HistogramPDFPageCount\n"); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbPdfRpcServer::PPB_PDF_UserMetricsRecordAction( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + nacl_abi_size_t action_size, char* action) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_Var pp_action = PP_MakeUndefined(); + if (!DeserializeTo(rpc->channel, action, action_size, 1, &pp_action)) + return; + PPBPDFInterface()->UserMetricsRecordAction(pp_action); + + DebugPrintf("PPB_PDF::UserMetricsRecordAction\n"); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbPdfRpcServer::PPB_PDF_HasUnsupportedFeature( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PPBPDFInterface()->HasUnsupportedFeature(instance); + + DebugPrintf("PPB_PDF::HasUnsupportedFeature: instance=%"NACL_PRId32"\n", + instance); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbPdfRpcServer::PPB_PDF_SaveAs( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PPBPDFInterface()->SaveAs(instance); + + DebugPrintf("PPB_PDF::SaveAs: instance=%"NACL_PRId32"\n", instance); + rpc->result = NACL_SRPC_RESULT_OK; +} + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_rpc_server.cc new file mode 100644 index 0000000..3b44366 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_rpc_server.cc @@ -0,0 +1,25 @@ +// Copyright (c) 2010 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_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "srpcgen/ppb_rpc.h" + +using ppapi_proxy::DebugPrintf; +using ppapi_proxy::GetBrowserInterface; + +void PpbRpcServer::PPB_GetInterface(NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + char* interface_name, + int32_t* exports_interface_name) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + // Since the proxy will make calls to proxied interfaces, we need simply + // to know whether the plugin exports a given interface. + const void* browser_interface = GetBrowserInterface(interface_name); + DebugPrintf("PPB_GetInterface('%s'): %p\n", + interface_name, browser_interface); + *exports_interface_name = (browser_interface != NULL); + rpc->result = NACL_SRPC_RESULT_OK; +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_scrollbar_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_scrollbar_rpc_server.cc new file mode 100644 index 0000000..1b98e18 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_scrollbar_rpc_server.cc @@ -0,0 +1,161 @@ +// 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. +// +// SRPC-abstraction wrappers around PPB_Scrollbar_Dev functions. + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "native_client/src/trusted/desc/nacl_desc_wrapper.h" +#include "ppapi/c/dev/ppb_scrollbar_dev.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_rect.h" +#include "ppapi/c/ppb_image_data.h" +#include "srpcgen/ppb_rpc.h" + +using ppapi_proxy::DebugPrintf; +using ppapi_proxy::PPBScrollbarInterface; + +void PpbScrollbarRpcServer::PPB_Scrollbar_Create( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t vertical, + PP_Resource* resource) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + PP_Bool pp_vertical = vertical ? PP_TRUE : PP_FALSE; + *resource = PPBScrollbarInterface()->Create(instance, pp_vertical); + DebugPrintf("PPB_Scrollbar::Create: resource=%"NACL_PRIu32"\n", *resource); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbScrollbarRpcServer::PPB_Scrollbar_IsScrollbar( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* is_scrollbar) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_Bool result = PPBScrollbarInterface()->IsScrollbar(resource); + *is_scrollbar = (result == PP_TRUE); + + DebugPrintf( + "PPB_Scrollbar::IsScrollbar: is_scrollbar=%"NACL_PRId32"\n", + *is_scrollbar); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbScrollbarRpcServer::PPB_Scrollbar_GetThickness( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* thickness) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + *thickness = PPBScrollbarInterface()->GetThickness(resource); + + DebugPrintf("PPB_Scrollbar::GetThickness: thickness=%"NACL_PRId32"\n", + *thickness); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbScrollbarRpcServer::PPB_Scrollbar_IsOverlay( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* is_overlay) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_Bool result = PPBScrollbarInterface()->IsOverlay(resource); + *is_overlay = (result == PP_TRUE); + + DebugPrintf( + "PPB_Scrollbar::IsScrollbar: is_overlay=%"NACL_PRId32"\n", + *is_overlay); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbScrollbarRpcServer::PPB_Scrollbar_GetValue( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource scrollbar, + int32_t* value) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + *value = PPBScrollbarInterface()->GetValue(scrollbar); + + DebugPrintf("PPB_Scrollbar::GetValue: value=%"NACL_PRId32"\n", + *value); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbScrollbarRpcServer::PPB_Scrollbar_SetValue( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource scrollbar, + int32_t value) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PPBScrollbarInterface()->SetValue(scrollbar, value); + + DebugPrintf("PPB_Scrollbar::SetValue\n"); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbScrollbarRpcServer::PPB_Scrollbar_SetDocumentSize( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource scrollbar, + int32_t size) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PPBScrollbarInterface()->SetDocumentSize(scrollbar, size); + + DebugPrintf("PPB_Scrollbar::SetDocumentSize\n"); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbScrollbarRpcServer::PPB_Scrollbar_SetTickMarks( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource scrollbar, + nacl_abi_size_t tick_marks_bytes, char* tick_marks, + int32_t count) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + if (tick_marks_bytes != count * sizeof(struct PP_Rect)) + return; + struct PP_Rect* pp_tick_marks = + reinterpret_cast<struct PP_Rect*>(tick_marks); + PPBScrollbarInterface()->SetTickMarks(scrollbar, pp_tick_marks, count); + + DebugPrintf("PPB_Scrollbar::SetTickMarks\n"); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbScrollbarRpcServer::PPB_Scrollbar_ScrollBy( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource scrollbar, + int32_t unit, + int32_t multiplier) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_ScrollBy_Dev pp_unit = static_cast<PP_ScrollBy_Dev>(unit); + PPBScrollbarInterface()->ScrollBy(scrollbar, pp_unit, multiplier); + + DebugPrintf("PPB_Scrollbar::ScrollBy\n"); + rpc->result = NACL_SRPC_RESULT_OK; +} + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_testing_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_testing_rpc_server.cc new file mode 100644 index 0000000..51729f1 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_testing_rpc_server.cc @@ -0,0 +1,93 @@ +// 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. +// +// SRPC-abstraction wrappers around PPB_Testing_Dev functions. + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/object_serialize.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "native_client/src/trusted/desc/nacl_desc_wrapper.h" +#include "ppapi/c/dev/ppb_testing_dev.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_point.h" +#include "srpcgen/ppb_rpc.h" + +using ppapi_proxy::DebugPrintf; +using ppapi_proxy::PPBTestingInterface; + +void PpbTestingRpcServer::PPB_Testing_ReadImageData( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource device_context_2d, + PP_Resource image, + nacl_abi_size_t top_left_size, char* top_left, + int32_t* success) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + if (top_left_size != sizeof(struct PP_Point)) + return; + struct PP_Point* pp_top_left = + reinterpret_cast<struct PP_Point*>(top_left); + + PP_Bool pp_success = + PPBTestingInterface()->ReadImageData(device_context_2d, + image, + pp_top_left); + *success = (pp_success == PP_TRUE); + + DebugPrintf("PPB_Testing_Dev::ReadImageData: " + "success=%"NACL_PRId32"\n", *success); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbTestingRpcServer::PPB_Testing_RunMessageLoop( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PPBTestingInterface()->RunMessageLoop(instance); + + DebugPrintf("PPB_Testing_Dev::RunMessageLoop: instance=%"NACL_PRIu32"\n", + instance); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbTestingRpcServer::PPB_Testing_QuitMessageLoop( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PPBTestingInterface()->QuitMessageLoop(instance); + + DebugPrintf("PPB_Testing_Dev::QuitMessageLoop: instance=%"NACL_PRIu32"\n", + instance); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbTestingRpcServer::PPB_Testing_GetLiveObjectsForInstance( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t* live_objects) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + uint32_t pp_live_objects = + PPBTestingInterface()->GetLiveObjectsForInstance(instance); + *live_objects = pp_live_objects; + + DebugPrintf("PPB_Testing_Dev::GetLiveObjectsForInstance: " + "live_objects=%"NACL_PRIu32"\n", *live_objects); + rpc->result = NACL_SRPC_RESULT_OK; +} + + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_url_loader_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_url_loader_rpc_server.cc new file mode 100644 index 0000000..c9ca60c --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_url_loader_rpc_server.cc @@ -0,0 +1,246 @@ +// 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. +// +// SRPC-abstraction wrappers around PPB_URLLoader functions. + +#include <stdio.h> +#include <string.h> + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/browser_callback.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/ppb_url_loader.h" +#include "srpcgen/ppb_rpc.h" + +using ppapi_proxy::PPBURLLoaderInterface; +using ppapi_proxy::DebugPrintf; +using ppapi_proxy::MakeRemoteCompletionCallback; +using ppapi_proxy::DeleteRemoteCallbackInfo; + +void PpbURLLoaderRpcServer::PPB_URLLoader_Create( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputsles + PP_Instance instance, + // outputs + PP_Resource* resource) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + *resource = PPBURLLoaderInterface()->Create(instance); + DebugPrintf("PPB_URLLoader::Create: resource=%"NACL_PRIu32"\n", *resource); + + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbURLLoaderRpcServer::PPB_URLLoader_IsURLLoader( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Resource resource, + // outputs + int32_t* success) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_Bool pp_success = PPBURLLoaderInterface()->IsURLLoader(resource); + DebugPrintf("PPB_URLLoader::IsURLLoader: pp_success=%d\n", pp_success); + + *success = (pp_success == PP_TRUE); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbURLLoaderRpcServer::PPB_URLLoader_Open( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Resource loader, + PP_Resource request, + int32_t callback_id, + // outputs + int32_t* pp_error) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_CompletionCallback remote_callback = + MakeRemoteCompletionCallback(rpc->channel, callback_id); + if (remote_callback.func == NULL) + return; + + *pp_error = PPBURLLoaderInterface()->Open(loader, request, remote_callback); + DebugPrintf("PPB_URLLoader::Open: pp_error=%"NACL_PRId32"\n", *pp_error); + + if (*pp_error != PP_OK_COMPLETIONPENDING) // Async error. + DeleteRemoteCallbackInfo(remote_callback); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbURLLoaderRpcServer::PPB_URLLoader_FollowRedirect( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Resource loader, + int32_t callback_id, + // outputs + int32_t* pp_error) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_CompletionCallback remote_callback = + MakeRemoteCompletionCallback(rpc->channel, callback_id); + if (remote_callback.func == NULL) + return; + + *pp_error = PPBURLLoaderInterface()->FollowRedirect(loader, remote_callback); + DebugPrintf("PPB_URLLoader::FollowRedirect: pp_error=%"NACL_PRId32"\n", + *pp_error); + if (*pp_error != PP_OK_COMPLETIONPENDING) // Async error. + DeleteRemoteCallbackInfo(remote_callback); + + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbURLLoaderRpcServer::PPB_URLLoader_GetUploadProgress( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Resource loader, + // outputs + int64_t* bytes_sent, + int64_t* total_bytes_to_be_sent, + int32_t* success) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_Bool pp_success = PPBURLLoaderInterface()->GetUploadProgress( + loader, bytes_sent, total_bytes_to_be_sent); + DebugPrintf("PPB_URLLoader::GetUploadProgress: pp_success=%d\n", pp_success); + + *success = (pp_success == PP_TRUE); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbURLLoaderRpcServer::PPB_URLLoader_GetDownloadProgress( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Resource loader, + // outputs + int64_t* bytes_received, + int64_t* total_bytes_to_be_received, + int32_t* success) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_Bool pp_success = PPBURLLoaderInterface()->GetDownloadProgress( + loader, bytes_received, total_bytes_to_be_received); + DebugPrintf("PPB_URLLoader::GetDownloadProgress: pp_success=%d\n", + pp_success); + + *success = (pp_success == PP_TRUE); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbURLLoaderRpcServer::PPB_URLLoader_GetResponseInfo( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Resource loader, + // outputs + PP_Resource* response) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + *response = PPBURLLoaderInterface()->GetResponseInfo(loader); + DebugPrintf("PPB_URLLoader::GetResponseInfo: response=%"NACL_PRIu32"\n", + *response); + + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbURLLoaderRpcServer::PPB_URLLoader_ReadResponseBody( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Resource loader, + int32_t bytes_to_read, + int32_t callback_id, + // outputs + nacl_abi_size_t* buffer_size, char* buffer, + int32_t* pp_error_or_bytes) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + CHECK(*buffer_size == static_cast<nacl_abi_size_t>(bytes_to_read)); + + // |buffer| is allocated by the rpc server and will be freed after this + // function returns. Hence we must provide our own byte storage for + // a non-blocking call and tie it to the callback. + char* callback_buffer = NULL; + PP_CompletionCallback remote_callback = MakeRemoteCompletionCallback( + rpc->channel, callback_id, bytes_to_read, &callback_buffer); + if (remote_callback.func == NULL) + return; + + *pp_error_or_bytes = PPBURLLoaderInterface()->ReadResponseBody( + loader, callback_buffer, bytes_to_read, remote_callback); + DebugPrintf("PPB_URLLoader::ReadResponseBody: pp_error_or_bytes=%" + NACL_PRId32"\n", *pp_error_or_bytes); + CHECK(*pp_error_or_bytes <= bytes_to_read); + + if (*pp_error_or_bytes > 0) { // Bytes read into |callback_buffer|. + // No callback scheduled. + *buffer_size = static_cast<nacl_abi_size_t>(*pp_error_or_bytes); + memcpy(buffer, callback_buffer, *buffer_size); + DeleteRemoteCallbackInfo(remote_callback); + } else if (*pp_error_or_bytes != PP_OK_COMPLETIONPENDING) { // Async error. + // No callback scheduled. + *buffer_size = 0; + DeleteRemoteCallbackInfo(remote_callback); + } else { + // Callback scheduled. + *buffer_size = 0; + } + + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbURLLoaderRpcServer::PPB_URLLoader_FinishStreamingToFile( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Resource loader, + int32_t callback_id, + // outputs + int32_t* pp_error) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_CompletionCallback remote_callback = + MakeRemoteCompletionCallback(rpc->channel, callback_id); + if (remote_callback.func == NULL) + return; + + *pp_error = + PPBURLLoaderInterface()->FinishStreamingToFile(loader, remote_callback); + DebugPrintf("PPB_URLLoader::FinishStreamingToFile: pp_error=%"NACL_PRId32"\n", + *pp_error); + if (*pp_error != PP_OK_COMPLETIONPENDING) // Async error. + DeleteRemoteCallbackInfo(remote_callback); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbURLLoaderRpcServer::PPB_URLLoader_Close( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Resource loader) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + PPBURLLoaderInterface()->Close(loader); + rpc->result = NACL_SRPC_RESULT_OK; +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_url_request_info_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_url_request_info_rpc_server.cc new file mode 100644 index 0000000..3f021f3 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_url_request_info_rpc_server.cc @@ -0,0 +1,124 @@ +// Copyright 2010 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. +// +// SRPC-abstraction wrappers around PPB_URLRequestInfo functions. + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/ppapi_proxy/object_serialize.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/ppb_url_request_info.h" +#include "srpcgen/ppb_rpc.h" + +using ppapi_proxy::PPBURLRequestInfoInterface; +using ppapi_proxy::DeserializeTo; +using ppapi_proxy::DebugPrintf; + +void PpbURLRequestInfoRpcServer::PPB_URLRequestInfo_Create( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Instance instance, + // outputs + PP_Resource* resource) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + *resource = PPBURLRequestInfoInterface()->Create(instance); + DebugPrintf("PPB_URLRequestInfo::Create: resource=%"NACL_PRIu32"\n", + *resource); + + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbURLRequestInfoRpcServer::PPB_URLRequestInfo_IsURLRequestInfo( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Resource resource, + // outputs + int32_t* success) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_Bool pp_success = PPBURLRequestInfoInterface()->IsURLRequestInfo(resource); + DebugPrintf("PPB_URLRequestInfo::IsURLRequestInfo: success=%d\n", pp_success); + + *success = (pp_success == PP_TRUE); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbURLRequestInfoRpcServer::PPB_URLRequestInfo_SetProperty( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Resource request, + int32_t property, + nacl_abi_size_t value_size, char* value_bytes, + // outputs + int32_t* success) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_Var value; + if (!DeserializeTo(rpc->channel, value_bytes, value_size, 1, &value)) + return; + + PP_Bool pp_success = PPBURLRequestInfoInterface()->SetProperty( + request, static_cast<PP_URLRequestProperty>(property), value); + DebugPrintf("PPB_URLRequestInfo::SetProperty: pp_success=%d\n", pp_success); + + *success = (pp_success == PP_TRUE); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbURLRequestInfoRpcServer::PPB_URLRequestInfo_AppendDataToBody( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Resource request, + nacl_abi_size_t data_size, char* data_bytes, + // outputs + int32_t* success) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_Bool pp_success = PPBURLRequestInfoInterface()->AppendDataToBody( + request, + static_cast<const char*>(data_bytes), + static_cast<uint32_t>(data_size)); + DebugPrintf("PPB_URLRequestInfo::AppendDataToBody: pp_success=%d\n", + pp_success); + + *success = (pp_success == PP_TRUE); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbURLRequestInfoRpcServer::PPB_URLRequestInfo_AppendFileToBody( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Resource request, + PP_Resource file_ref, + int64_t start_offset, + int64_t number_of_bytes, + double expected_last_modified_time, + // outputs + int32_t* success) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_Bool pp_success = PPBURLRequestInfoInterface()->AppendFileToBody( + request, + file_ref, + start_offset, + number_of_bytes, + static_cast<PP_Time>(expected_last_modified_time)); + DebugPrintf("PPB_URLRequestInfo::AppendFileToBody: pp_success=%d\n", + pp_success); + + *success = (pp_success == PP_TRUE); + rpc->result = NACL_SRPC_RESULT_OK; +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_url_response_info_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_url_response_info_rpc_server.cc new file mode 100644 index 0000000..fdac4e2 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_url_response_info_rpc_server.cc @@ -0,0 +1,73 @@ +// Copyright 2010 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. +// +// SRPC-abstraction wrappers around PPB_URLResponseInfo functions. + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/ppapi_proxy/object_serialize.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/ppb_url_response_info.h" +#include "srpcgen/ppb_rpc.h" + +using ppapi_proxy::PPBURLResponseInfoInterface; +using ppapi_proxy::SerializeTo; +using ppapi_proxy::DebugPrintf; + +void PpbURLResponseInfoRpcServer::PPB_URLResponseInfo_IsURLResponseInfo( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Resource resource, + // outputs + int32_t* success) { + NaClSrpcClosureRunner runner(done); + + PP_Bool pp_success = + PPBURLResponseInfoInterface()->IsURLResponseInfo(resource); + DebugPrintf("PPB_URLResponseInfo::IsURLResponseInfo: pp_success=%d\n", + pp_success); + + *success = (pp_success == PP_TRUE); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbURLResponseInfoRpcServer::PPB_URLResponseInfo_GetProperty( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Resource response, + int32_t property, + // outputs + nacl_abi_size_t* value_size, char* value_bytes) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_Var value = PPBURLResponseInfoInterface()->GetProperty( + response, static_cast<PP_URLResponseProperty>(property)); + DebugPrintf("PPB_URLResponseInfo::GetProperty: type=%d\n", + value.type); + + if (!SerializeTo(&value, value_bytes, value_size)) + return; + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbURLResponseInfoRpcServer::PPB_URLResponseInfo_GetBodyAsFileRef( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Resource response, + // outputs + PP_Resource* file_ref) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + *file_ref = PPBURLResponseInfoInterface()->GetBodyAsFileRef(response); + DebugPrintf("PPB_URLResponseInfo::GetBodyAsFileRef: file_ref="NACL_PRIu32"\n", + *file_ref); + + rpc->result = NACL_SRPC_RESULT_OK; +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_widget_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_widget_rpc_server.cc new file mode 100644 index 0000000..cf56f15 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_widget_rpc_server.cc @@ -0,0 +1,110 @@ +// 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. +// +// SRPC-abstraction wrappers around PPB_Widget_Dev functions. + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "native_client/src/trusted/desc/nacl_desc_wrapper.h" +#include "ppapi/c/dev/ppb_widget_dev.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_input_event.h" +#include "ppapi/c/pp_rect.h" +#include "ppapi/c/ppb_image_data.h" +#include "srpcgen/ppb_rpc.h" + +using ppapi_proxy::DebugPrintf; +using ppapi_proxy::PPBWidgetInterface; + +void PpbWidgetRpcServer::PPB_Widget_IsWidget( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* is_widget) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PP_Bool pp_is_widget = PPBWidgetInterface()->IsWidget(resource); + *is_widget = (pp_is_widget == PP_TRUE); + + DebugPrintf("PPB_Widget::Widget: resource=%"NACL_PRIu32"\n", + resource); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbWidgetRpcServer::PPB_Widget_Paint( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource widget, + nacl_abi_size_t rect_size, char* rect, + PP_Resource image, + int32_t* success) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + if (rect_size != sizeof(struct PP_Rect)) + return; + struct PP_Rect* pp_rect = reinterpret_cast<struct PP_Rect*>(rect); + *success = PPBWidgetInterface()->Paint(widget, pp_rect, image); + + DebugPrintf("PPB_Widget::Paint: widget=%"NACL_PRIu32"\n", + widget); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbWidgetRpcServer::PPB_Widget_HandleEvent( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource widget, + PP_Resource pp_event, + int32_t* handled) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + *handled = PPBWidgetInterface()->HandleEvent(widget, pp_event); + + DebugPrintf("PPB_Widget::HandleEvent: widget=%"NACL_PRIu32"\n", + widget); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbWidgetRpcServer::PPB_Widget_GetLocation( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource widget, + nacl_abi_size_t* rect_size, char* rect, + int32_t* visible) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + if (*rect_size != sizeof(struct PP_Rect)) + return; + struct PP_Rect* pp_rect = reinterpret_cast<struct PP_Rect*>(rect); + *visible = PPBWidgetInterface()->GetLocation(widget, pp_rect); + + DebugPrintf("PPB_Widget::GetLocation: widget=%"NACL_PRIu32"\n", + widget); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbWidgetRpcServer::PPB_Widget_SetLocation( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource widget, + nacl_abi_size_t rect_size, char* rect) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + if (rect_size != sizeof(struct PP_Rect)) + return; + struct PP_Rect* pp_rect = reinterpret_cast<struct PP_Rect*>(rect); + PPBWidgetInterface()->SetLocation(widget, pp_rect); + + DebugPrintf("PPB_Widget::SetLocation: widget=%"NACL_PRIu32"\n", + widget); + rpc->result = NACL_SRPC_RESULT_OK; +} + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_zoom_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_zoom_rpc_server.cc new file mode 100644 index 0000000..02000ed --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_zoom_rpc_server.cc @@ -0,0 +1,53 @@ +// 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. +// +// SRPC-abstraction wrappers around PPB_Zoom_Dev functions. + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "native_client/src/trusted/desc/nacl_desc_wrapper.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_point.h" +#include "ppapi/c/ppb_image_data.h" +#include "srpcgen/ppb_rpc.h" + +using ppapi_proxy::DebugPrintf; +using ppapi_proxy::PPBZoomInterface; + +void PpbZoomRpcServer::PPB_Zoom_ZoomChanged( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + double factor) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PPBZoomInterface()->ZoomChanged(instance, factor); + + DebugPrintf("PPB_Zoom::ZoomChanged: instance=%"NACL_PRIu32"\n", + instance); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PpbZoomRpcServer::PPB_Zoom_ZoomLimitsChanged( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + double minimum_factor, + double maximum_factor) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + PPBZoomInterface()->ZoomLimitsChanged(instance, + minimum_factor, + maximum_factor); + + DebugPrintf("PPB_Zoom::ZoomLimitsChanged: instance=%"NACL_PRIu32"\n", + instance); + rpc->result = NACL_SRPC_RESULT_OK; +} + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp.cc new file mode 100644 index 0000000..1227f3e --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp.cc @@ -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 diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp.h b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp.h new file mode 100644 index 0000000..3ae6561 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp.h @@ -0,0 +1,100 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_PPP_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_PPP_H_ + +#include <stdarg.h> + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/src/shared/platform/nacl_threads.h" +#include "native_client/src/trusted/desc/nacl_desc_invalid.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/ppp.h" +#include "ppapi/c/ppp_instance.h" +#include "ppapi/c/ppp_messaging.h" + +namespace plugin { +class Plugin; +} + +struct PPP_InputEvent; + +namespace ppapi_proxy { + +class BrowserPpp { + public: + BrowserPpp(NaClSrpcChannel* main_channel, plugin::Plugin* plugin) + : main_channel_(main_channel), + is_nexe_alive_(true), + plugin_pid_(0), + plugin_(plugin), + ppp_instance_interface_(NULL), + ppp_messaging_interface_(NULL), + ppp_input_event_interface_(NULL) { + CHECK(main_channel_ != NULL); + } + + ~BrowserPpp() {} + + int32_t InitializeModule(PP_Module module_id, + PPB_GetInterface get_browser_interface); + + // Joins upcall thread, drops references to channel (owned by plugin), + // calls plugin side shutdown, but not user's PPP_ShutdownModule. + void ShutdownModule(); + // Returns an interface pointer or NULL. + const void* GetPluginInterface(const char* interface_name); + // Returns an interface pointer or fails on a NULL CHECK. + const void* GetPluginInterfaceSafe(const char* interface_name); + + // Guaranteed to be non-NULL if module initialization succeeded. + // Use this instead of GetPluginInterface for PPP_INSTANCE_INTERFACE. + const PPP_Instance* ppp_instance_interface() const { + return ppp_instance_interface_; + } + + const PPP_Messaging* ppp_messaging_interface() const { + return ppp_messaging_interface_; + } + + const PPP_InputEvent* ppp_input_event_interface() const { + return ppp_input_event_interface_; + } + + bool is_valid() const { return is_nexe_alive_; } + static bool is_valid(BrowserPpp* proxy) { + return (proxy != NULL && proxy->is_valid()); + } + + NaClSrpcChannel* main_channel() const { return main_channel_; } + int plugin_pid() const { return plugin_pid_; } + plugin::Plugin* plugin() { return plugin_; } + + private: + // The "main" SRPC channel used to communicate with the plugin. + // NULL if proxy has been shut down. + NaClSrpcChannel* main_channel_; + bool is_nexe_alive_; + // The PID of the plugin. + int plugin_pid_; + // Plugin that owns this proxy. + plugin::Plugin* plugin_; + + // Set on module initialization. + const PPP_Instance* ppp_instance_interface_; + const PPP_Messaging* ppp_messaging_interface_; + const PPP_InputEvent* ppp_input_event_interface_; + + // The thread used to handle calls on other than the main thread. + struct NaClThread upcall_thread_; + NACL_DISALLOW_COPY_AND_ASSIGN(BrowserPpp); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_PPP_H_ diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_find.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_find.cc new file mode 100644 index 0000000..d8c9fa2 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_find.cc @@ -0,0 +1,78 @@ +// 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_find.h" + +#include <string.h> + +// Include file order cannot be observed because ppp_instance declares a +// structure return type that causes an error on Windows. +// TODO(sehr, brettw): fix the return types and include order in PPAPI. +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_resource.h" +#include "srpcgen/ppp_rpc.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/ppapi_proxy/browser_ppp.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" + +namespace ppapi_proxy { + +namespace { + +PP_Bool StartFind(PP_Instance instance, + const char* text, + PP_Bool case_sensitive) { + DebugPrintf("PPP_Find::StartFind: instance=%"NACL_PRIu32"\n", instance); + + int32_t supports_find = 0; + nacl_abi_size_t text_bytes = static_cast<nacl_abi_size_t>(strlen(text)); + NaClSrpcError srpc_result = PppFindRpcClient::PPP_Find_StartFind( + GetMainSrpcChannel(instance), + instance, + text_bytes, const_cast<char*>(text), + static_cast<int32_t>(case_sensitive), + &supports_find); + + DebugPrintf("PPP_Find::StartFind: %s\n", NaClSrpcErrorString(srpc_result)); + return supports_find ? PP_TRUE : PP_FALSE; +} + +void SelectFindResult(PP_Instance instance, + PP_Bool forward) { + DebugPrintf("PPP_Find::SelectFindResult: " + "instance=%"NACL_PRIu32"\n", instance); + + NaClSrpcError srpc_result = PppFindRpcClient::PPP_Find_SelectFindResult( + GetMainSrpcChannel(instance), + instance, + static_cast<int32_t>(forward)); + + DebugPrintf("PPP_Find::SelectFindResult: %s\n", + NaClSrpcErrorString(srpc_result)); +} + +void StopFind(PP_Instance instance) { + DebugPrintf("PPP_Find::StopFind: instance=%"NACL_PRIu32"\n", instance); + + NaClSrpcError srpc_result = PppFindRpcClient::PPP_Find_StopFind( + GetMainSrpcChannel(instance), + instance); + + DebugPrintf("PPP_Find::StopFind: %s\n", NaClSrpcErrorString(srpc_result)); +} + +} // namespace + +const PPP_Find_Dev* BrowserFind::GetInterface() { + static const PPP_Find_Dev find_interface = { + StartFind, + SelectFindResult, + StopFind + }; + return &find_interface; +} + +} // namespace ppapi_proxy + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_find.h b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_find.h new file mode 100644 index 0000000..12201e1 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_find.h @@ -0,0 +1,27 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_PPP_FIND_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_PPP_FIND_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "ppapi/c/dev/ppp_find_dev.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/pp_var.h" + +namespace ppapi_proxy { + +// Implements the trusted side of the PPP_Find_Dev interface. +class BrowserFind { + public: + static const PPP_Find_Dev* GetInterface(); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(BrowserFind); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_PPP_FIND_H_ + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_input_event.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_input_event.cc new file mode 100644 index 0000000..f71aecb --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_input_event.cc @@ -0,0 +1,115 @@ +// 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_input_event.h" + +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/ppapi_proxy/input_event_data.h" +#include "native_client/src/shared/ppapi_proxy/object_serialize.h" +#include "native_client/src/shared/ppapi_proxy/browser_ppp.h" +#include "native_client/src/shared/ppapi_proxy/trusted/srpcgen/ppp_rpc.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/ppp_input_event.h" + +namespace ppapi_proxy { + +namespace { + +PP_Bool HandleInputEvent(PP_Instance instance, PP_Resource input_event) { + DebugPrintf("PPP_InputEvent::HandleInputEvent: instance=%"NACL_PRIu32", " + "input_event = %"NACL_PRIu32"\n", + instance, input_event); + + PP_Var character_text = PP_MakeUndefined(); + InputEventData data; + data.event_type = PPBInputEventInterface()->GetType(input_event); + data.event_time_stamp = PPBInputEventInterface()->GetTimeStamp(input_event); + data.event_modifiers = PPBInputEventInterface()->GetModifiers(input_event); + + switch (data.event_type) { + // These events all use the PPB_MouseInputEvent interface. + case PP_INPUTEVENT_TYPE_MOUSEDOWN: + case PP_INPUTEVENT_TYPE_MOUSEUP: + case PP_INPUTEVENT_TYPE_MOUSEENTER: + case PP_INPUTEVENT_TYPE_MOUSELEAVE: + case PP_INPUTEVENT_TYPE_MOUSEMOVE: + case PP_INPUTEVENT_TYPE_CONTEXTMENU: + data.mouse_button = + PPBMouseInputEventInterface()->GetButton(input_event); + data.mouse_position = + PPBMouseInputEventInterface()->GetPosition(input_event); + data.mouse_click_count = + PPBMouseInputEventInterface()->GetClickCount(input_event); + break; + // This event uses the PPB_WheelInputEvent interface. + case PP_INPUTEVENT_TYPE_WHEEL: + data.wheel_delta = + PPBWheelInputEventInterface()->GetDelta(input_event); + data.wheel_ticks = + PPBWheelInputEventInterface()->GetTicks(input_event); + data.wheel_scroll_by_page = + PPBWheelInputEventInterface()->GetScrollByPage(input_event); + break; + // These events all use the PPB_KeyInputEvent interface. + case PP_INPUTEVENT_TYPE_RAWKEYDOWN: + case PP_INPUTEVENT_TYPE_KEYDOWN: + case PP_INPUTEVENT_TYPE_KEYUP: + case PP_INPUTEVENT_TYPE_CHAR: + data.key_code = + PPBKeyboardInputEventInterface()->GetKeyCode(input_event); + character_text = + PPBKeyboardInputEventInterface()->GetCharacterText(input_event); + break; + case PP_INPUTEVENT_TYPE_UNDEFINED: + return PP_FALSE; + // No default case; if any new types are added we should get a compile + // warning. + } + // Now data and character_text have all the data we want to send to the + // untrusted side. + + // character_text should either be undefined or a string type. + DCHECK((character_text.type == PP_VARTYPE_UNDEFINED) || + (character_text.type == PP_VARTYPE_STRING)); + // Serialize the character_text Var. + uint32_t text_size = kMaxVarSize; + nacl::scoped_array<char> text_bytes(Serialize(&character_text, 1, + &text_size)); + int32_t handled; + NaClSrpcError srpc_result = + PppInputEventRpcClient::PPP_InputEvent_HandleInputEvent( + GetMainSrpcChannel(instance), + instance, + input_event, + sizeof(data), + reinterpret_cast<char*>(&data), + text_size, + text_bytes.get(), + &handled); + DebugPrintf("PPP_Instance::HandleInputEvent: %s\n", + NaClSrpcErrorString(srpc_result)); + if (srpc_result != NACL_SRPC_RESULT_OK) { + return PP_FALSE; + } + // The 'handled' int should only ever have a value matching one of PP_FALSE + // or PP_TRUE. Otherwise, there's an error in the proxy. + DCHECK((handled == static_cast<int32_t>(PP_FALSE) || + (handled == static_cast<int32_t>(PP_TRUE)))); + PP_Bool handled_bool = static_cast<PP_Bool>(handled); + return handled_bool; +} + +} // namespace + +const PPP_InputEvent* BrowserInputEvent::GetInterface() { + static const PPP_InputEvent input_event_interface = { + HandleInputEvent + }; + return &input_event_interface; +} + +} // namespace ppapi_proxy diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_input_event.h b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_input_event.h new file mode 100644 index 0000000..748e469 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_input_event.h @@ -0,0 +1,31 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_INPUT_EVENT_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_INPUT_EVENT_H_ + +#include <map> + +#include "native_client/src/include/nacl_macros.h" +// Needed because ppp_instance.h does not include everything it needs. +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/ppb_input_event.h" + +struct PPP_InputEvent; + +namespace ppapi_proxy { + +// Implements the trusted side of the PPP_InputEvent interface. +class BrowserInputEvent { + public: + static const PPP_InputEvent* GetInterface(); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(BrowserInputEvent); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_INPUT_EVENT_H_ diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_instance.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_instance.cc new file mode 100644 index 0000000..d2446ae --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_instance.cc @@ -0,0 +1,174 @@ +// 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_instance.h" + +#include <stdio.h> +#include <string.h> +#include <limits> + +#include "native_client/src/include/checked_cast.h" +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/ppapi_proxy/browser_ppp.h" +#include "native_client/src/shared/ppapi_proxy/trusted/srpcgen/ppp_rpc.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/pp_var.h" +#include "ppapi/c/ppp_instance.h" + +using nacl::scoped_array; + +namespace ppapi_proxy { + +namespace { + +char* ArgArraySerialize(int argc, + const char* array[], + uint32_t* serial_size) { + uint32_t used = 0; + for (int i = 0; i < argc; ++i) { + // Note that strlen() cannot ever return SIZE_T_MAX, since that would imply + // that there were no nulls anywhere in memory, which would lead to + // strlen() never terminating. So this assignment is safe. + size_t len = strlen(array[i]) + 1; + if (len > std::numeric_limits<uint32_t>::max()) { + // Overflow, input string is too long. + return NULL; + } + if (used > std::numeric_limits<uint32_t>::max() - len) { + // Overflow, output string is too long. + return NULL; + } + used += static_cast<uint32_t>(len); + } + // Note that there is a check against numeric_limits<uint32_t> in the code + // above, which is why this cast is safe. + *serial_size = used; + char* serial_array = new char[used]; + + size_t pos = 0; + for (int i = 0; i < argc; ++i) { + size_t len = strlen(array[i]) + 1; + strncpy(serial_array + pos, array[i], len); + pos += len; + } + return serial_array; +} + +PP_Bool DidCreate(PP_Instance instance, + uint32_t argc, + const char* argn[], + const char* argv[]) { + DebugPrintf("PPP_Instance::DidCreate: instance=%"NACL_PRIu32"\n", instance); + uint32_t argn_size; + scoped_array<char> argn_serial(ArgArraySerialize(argc, argn, &argn_size)); + if (argn_serial.get() == NULL) { + return PP_FALSE; + } + uint32_t argv_size; + scoped_array<char> argv_serial(ArgArraySerialize(argc, argv, &argv_size)); + if (argv_serial.get() == NULL) { + return PP_FALSE; + } + int32_t int_argc = static_cast<int32_t>(argc); + int32_t success; + NaClSrpcError srpc_result = + PppInstanceRpcClient::PPP_Instance_DidCreate(GetMainSrpcChannel(instance), + instance, + int_argc, + argn_size, + argn_serial.get(), + argv_size, + argv_serial.get(), + &success); + DebugPrintf("PPP_Instance::DidCreate: %s\n", + NaClSrpcErrorString(srpc_result)); + if (srpc_result != NACL_SRPC_RESULT_OK) { + return PP_FALSE; + } + return static_cast<PP_Bool>(success != 0); +} + +void DidDestroy(PP_Instance instance) { + DebugPrintf("PPP_Instance::DidDestroy: instance=%"NACL_PRIu32"\n", instance); + NaClSrpcError srpc_result = PppInstanceRpcClient::PPP_Instance_DidDestroy( + GetMainSrpcChannel(instance), instance); + DebugPrintf("PPP_Instance::DidDestroy: %s\n", + NaClSrpcErrorString(srpc_result)); +} + +void DidChangeView(PP_Instance instance, + const PP_Rect* position, + const PP_Rect* clip) { + DebugPrintf("PPP_Instance::DidChangeView: instance=%"NACL_PRIu32"\n", + instance); + int32_t position_array[4]; + const uint32_t kPositionArraySize = NACL_ARRAY_SIZE(position_array); + position_array[0] = position->point.x; + position_array[1] = position->point.y; + position_array[2] = position->size.width; + position_array[3] = position->size.height; + int32_t clip_array[4]; + const uint32_t kClipArraySize = NACL_ARRAY_SIZE(clip_array); + clip_array[0] = clip->point.x; + clip_array[1] = clip->point.y; + clip_array[2] = clip->size.width; + clip_array[3] = clip->size.height; + NaClSrpcError srpc_result = PppInstanceRpcClient::PPP_Instance_DidChangeView( + GetMainSrpcChannel(instance), + instance, + kPositionArraySize, + position_array, + kClipArraySize, + clip_array); + DebugPrintf("PPP_Instance::DidChangeView: %s\n", + NaClSrpcErrorString(srpc_result)); +} + +void DidChangeFocus(PP_Instance instance, PP_Bool has_focus) { + DebugPrintf("PPP_Instance::DidChangeFocus: instance=%"NACL_PRIu32", " + "has_focus = %d\n", instance, has_focus); + NaClSrpcError srpc_result = PppInstanceRpcClient::PPP_Instance_DidChangeFocus( + GetMainSrpcChannel(instance), + instance, + static_cast<bool>(PP_TRUE == has_focus)); + DebugPrintf("PPP_Instance::DidChangeFocus: %s\n", + NaClSrpcErrorString(srpc_result)); +} + +PP_Bool HandleDocumentLoad(PP_Instance instance, PP_Resource url_loader) { + DebugPrintf("PPP_Instance::HandleDocumentLoad: instance=%"NACL_PRIu32", " + "url_loader=%"NACL_PRIu32"\n", instance, url_loader); + + int32_t result = 0; + NaClSrpcError srpc_result = + PppInstanceRpcClient::PPP_Instance_HandleDocumentLoad( + GetMainSrpcChannel(instance), + instance, + url_loader, + &result); + + DebugPrintf("PPP_Instance::HandleDocumentLoad: %s\n", + NaClSrpcErrorString(srpc_result)); + if (srpc_result == NACL_SRPC_RESULT_OK && result) + return PP_TRUE; + return PP_FALSE; +} + +} // namespace + +const PPP_Instance* BrowserInstance::GetInterface() { + static const PPP_Instance instance_interface = { + DidCreate, + DidDestroy, + DidChangeView, + DidChangeFocus, + HandleDocumentLoad + }; + return &instance_interface; +} + +} // namespace ppapi_proxy diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_instance.h b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_instance.h new file mode 100644 index 0000000..9fd8a7f --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_instance.h @@ -0,0 +1,27 @@ +// Copyright 2010 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_INSTANCE_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_INSTANCE_H_ + +#include "native_client/src/include/nacl_macros.h" +// Needed because ppp_instance.h does not include everything it needs. +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/pp_var.h" +#include "ppapi/c/ppp_instance.h" + +namespace ppapi_proxy { + +// Implements the trusted side of the PPP_Instance interface. +class BrowserInstance { + public: + static const PPP_Instance* GetInterface(); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(BrowserInstance); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_INSTANCE_H_ diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_messaging.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_messaging.cc new file mode 100644 index 0000000..5dc3b5a --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_messaging.cc @@ -0,0 +1,46 @@ +// 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_messaging.h" + +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/ppapi_proxy/object_serialize.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_var.h" +#include "srpcgen/ppp_rpc.h" + +namespace ppapi_proxy { + +namespace { + +void HandleMessage(PP_Instance instance, struct PP_Var message) { + DebugPrintf("PPP_Messaging::HandleMessage: instance=%"NACL_PRIu32"\n", + instance); + uint32_t message_length = kMaxVarSize; + nacl::scoped_array<char> message_bytes(Serialize(&message, 1, + &message_length)); + NaClSrpcError srpc_result = + PppMessagingRpcClient::PPP_Messaging_HandleMessage( + GetMainSrpcChannel(instance), + instance, + message_length, + message_bytes.get()); + + DebugPrintf("PPP_Messaging::HandleMessage: %s\n", + NaClSrpcErrorString(srpc_result)); +} + +} // namespace + +const PPP_Messaging* BrowserMessaging::GetInterface() { + static const PPP_Messaging messaging_interface = { + HandleMessage + }; + return &messaging_interface; +} + +} // namespace ppapi_proxy + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_messaging.h b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_messaging.h new file mode 100644 index 0000000..7d5b21b --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_messaging.h @@ -0,0 +1,25 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_PPP_MESSAGING_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_PPP_MESSAGING_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "ppapi/c/ppp_messaging.h" + +namespace ppapi_proxy { + +// Implements the trusted side of the PPP_Messaging interface. +class BrowserMessaging { + public: + static const PPP_Messaging* GetInterface(); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(BrowserMessaging); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_PPP_MESSAGING_H_ + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_printing.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_printing.cc new file mode 100644 index 0000000..ae96a62 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_printing.cc @@ -0,0 +1,120 @@ +// 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_printing.h" + +// Include file order cannot be observed because ppp_instance declares a +// structure return type that causes an error on Windows. +// TODO(sehr, brettw): fix the return types and include order in PPAPI. +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_resource.h" +#include "srpcgen/ppp_rpc.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/ppapi_proxy/browser_ppp.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" + +namespace ppapi_proxy { + +namespace { + +const nacl_abi_size_t kPPPrintOutputFormatBytes = + static_cast<nacl_abi_size_t>(sizeof(PP_PrintOutputFormat_Dev)); +const nacl_abi_size_t kPPPrintSettingsBytes = + static_cast<nacl_abi_size_t>(sizeof(struct PP_PrintSettings_Dev)); +const nacl_abi_size_t kPPPrintPageNumberRangeBytes = + static_cast<nacl_abi_size_t>(sizeof(struct PP_PrintPageNumberRange_Dev)); + +PP_PrintOutputFormat_Dev* QuerySupportedFormats(PP_Instance instance, + uint32_t* format_count) { + DebugPrintf("PPP_Printing_Dev::QuerySupportedFormats: " + "instance=%"NACL_PRIu32"\n", instance); + + const PPB_Memory_Dev* ppb_memory = PPBMemoryInterface(); + const nacl_abi_size_t kMaxFormats = 8; + nacl_abi_size_t formats_bytes = kMaxFormats * kPPPrintOutputFormatBytes; + char* formats = + reinterpret_cast<char*>(ppb_memory->MemAlloc(formats_bytes)); + NaClSrpcError srpc_result = + PppPrintingRpcClient::PPP_Printing_QuerySupportedFormats( + GetMainSrpcChannel(instance), + instance, + &formats_bytes, formats, + reinterpret_cast<int32_t*>(format_count)); + + DebugPrintf("PPP_Printing_Dev::QuerySupportedFormats: %s\n", + NaClSrpcErrorString(srpc_result)); + + if (*format_count > 0) + return reinterpret_cast<PP_PrintOutputFormat_Dev*>(formats); + + ppb_memory->MemFree(formats); + return NULL; +} + +int32_t Begin(PP_Instance instance, + const struct PP_PrintSettings_Dev* print_settings) { + DebugPrintf("PPP_Printing_Dev::Begin: instance=%"NACL_PRIu32"\n", instance); + + int32_t pages_required = 0; + NaClSrpcError srpc_result = + PppPrintingRpcClient::PPP_Printing_Begin( + GetMainSrpcChannel(instance), + instance, + kPPPrintSettingsBytes, + reinterpret_cast<char*>( + const_cast<PP_PrintSettings_Dev*>(print_settings)), + &pages_required); + + DebugPrintf("PPP_Printing_Dev::QuerySupportedFormats: %s\n", + NaClSrpcErrorString(srpc_result)); + return pages_required; +} + +PP_Resource PrintPages(PP_Instance instance, + const struct PP_PrintPageNumberRange_Dev* page_ranges, + uint32_t page_range_count) { + DebugPrintf("PPP_Printing_Dev::PrintPages: " + "instance=%"NACL_PRIu32"\n", instance); + + PP_Resource image_data = kInvalidResourceId; + NaClSrpcError srpc_result = + PppPrintingRpcClient::PPP_Printing_PrintPages( + GetMainSrpcChannel(instance), + instance, + page_range_count * kPPPrintPageNumberRangeBytes, + reinterpret_cast<char*>( + const_cast<PP_PrintPageNumberRange_Dev*>(page_ranges)), + page_range_count, + &image_data); + + DebugPrintf("PPP_Printing_Dev::QuerySupportedFormats: %s\n", + NaClSrpcErrorString(srpc_result)); + return image_data; +} + +void End(PP_Instance instance) { + DebugPrintf("PPP_Printing_Dev::End: instance=%"NACL_PRIu32"\n", instance); + + NaClSrpcError srpc_result = + PppPrintingRpcClient::PPP_Printing_End(GetMainSrpcChannel(instance), + instance); + + DebugPrintf("PPP_Printing_Dev::End: %s\n", NaClSrpcErrorString(srpc_result)); +} + +} // namespace + +const PPP_Printing_Dev* BrowserPrinting::GetInterface() { + static const PPP_Printing_Dev printing_interface = { + QuerySupportedFormats, + Begin, + PrintPages, + End + }; + return &printing_interface; +} + +} // namespace ppapi_proxy + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_printing.h b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_printing.h new file mode 100644 index 0000000..c23b245f --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_printing.h @@ -0,0 +1,27 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_PPP_PRINTING_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_PPP_PRINTING_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "ppapi/c/dev/ppp_printing_dev.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/pp_var.h" + +namespace ppapi_proxy { + +// Implements the trusted side of the PPP_Printing_Dev interface. +class BrowserPrinting { + public: + static const PPP_Printing_Dev* GetInterface(); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(BrowserPrinting); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_PPP_PRINTING_H_ + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_scrollbar.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_scrollbar.cc new file mode 100644 index 0000000..586b34a --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_scrollbar.cc @@ -0,0 +1,68 @@ +// 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_scrollbar.h" + +// Include file order cannot be observed because ppp_instance declares a +// structure return type that causes an error on Windows. +// TODO(sehr, brettw): fix the return types and include order in PPAPI. +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_resource.h" +#include "srpcgen/ppp_rpc.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/ppapi_proxy/browser_ppp.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" + +namespace ppapi_proxy { + +namespace { + +void ValueChanged( + PP_Instance instance, + PP_Resource resource, + uint32_t value) { + DebugPrintf("PPP_Scrollbar_Dev::ValueChanged: instance=%"NACL_PRIu32"\n", + instance); + + NaClSrpcError srpc_result = PppScrollbarRpcClient::PPP_Scrollbar_ValueChanged( + GetMainSrpcChannel(instance), + instance, + resource, + value); + + DebugPrintf("PPP_Scrollbar_Dev::ValueChanged: %s\n", + NaClSrpcErrorString(srpc_result)); +} + +void OverlayChanged( + PP_Instance instance, + PP_Resource resource, + PP_Bool type) { + DebugPrintf("PPP_Scrollbar_Dev::OverlayChanged: instance=%"NACL_PRIu32"\n", + instance); + + NaClSrpcError srpc_result = + PppScrollbarRpcClient::PPP_Scrollbar_OverlayChanged( + GetMainSrpcChannel(instance), + instance, + resource, + type); + + DebugPrintf("PPP_Scrollbar_Dev::OverlayChanged: %s\n", + NaClSrpcErrorString(srpc_result)); +} + +} // namespace + +const PPP_Scrollbar_Dev* BrowserScrollbar::GetInterface() { + static const PPP_Scrollbar_Dev scrollbar_interface = { + ValueChanged, + OverlayChanged + }; + return &scrollbar_interface; +} + +} // namespace ppapi_proxy + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_scrollbar.h b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_scrollbar.h new file mode 100644 index 0000000..059f466 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_scrollbar.h @@ -0,0 +1,27 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_PPP_SCROLLBAR_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_PPP_SCROLLBAR_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "ppapi/c/dev/ppp_scrollbar_dev.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/pp_var.h" + +namespace ppapi_proxy { + +// Implements the trusted side of the PPP_Scrollbar_Dev interface. +class BrowserScrollbar { + public: + static const PPP_Scrollbar_Dev* GetInterface(); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(BrowserScrollbar); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_PPP_SCROLLBAR_H_ + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_selection.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_selection.cc new file mode 100644 index 0000000..022a9e4 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_selection.cc @@ -0,0 +1,60 @@ +// 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_selection.h" + +// Include file order cannot be observed because ppp_instance declares a +// structure return type that causes an error on Windows. +// TODO(sehr, brettw): fix the return types and include order in PPAPI. +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_rect.h" +#include "ppapi/c/pp_resource.h" +#include "srpcgen/ppp_rpc.h" +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/ppapi_proxy/browser_ppp.h" +#include "native_client/src/shared/ppapi_proxy/object_serialize.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" + +namespace ppapi_proxy { + +namespace { + +struct PP_Var GetSelectedText(PP_Instance instance, PP_Bool html) { + DebugPrintf("PPP_Selection_Dev::GetSelectedText: " + "instance=%"NACL_PRIu32"\n", instance); + NaClSrpcChannel* channel = GetMainSrpcChannel(instance); + nacl_abi_size_t text_size = kMaxVarSize; + nacl::scoped_array<char> text_bytes(new char[kMaxVarSize]); + NaClSrpcError srpc_result = + PppSelectionRpcClient::PPP_Selection_GetSelectedText( + channel, + instance, + static_cast<int32_t>(html), + &text_size, + text_bytes.get()); + + DebugPrintf("PPP_Selection_Dev::GetSelectedText: %s\n", + NaClSrpcErrorString(srpc_result)); + + PP_Var selected_text = PP_MakeUndefined(); + if (srpc_result == NACL_SRPC_RESULT_OK) { + (void) DeserializeTo( + channel, text_bytes.get(), text_size, 1, &selected_text); + } + return selected_text; +} + +} // namespace + +const PPP_Selection_Dev* BrowserSelection::GetInterface() { + static const PPP_Selection_Dev selection_interface = { + GetSelectedText + }; + return &selection_interface; +} + +} // namespace ppapi_proxy + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_selection.h b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_selection.h new file mode 100644 index 0000000..9cb3559 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_selection.h @@ -0,0 +1,27 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_PPP_SELECTION_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_PPP_SELECTION_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "ppapi/c/dev/ppp_selection_dev.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/pp_var.h" + +namespace ppapi_proxy { + +// Implements the trusted side of the PPP_Selection_Dev interface. +class BrowserSelection { + public: + static const PPP_Selection_Dev* GetInterface(); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(BrowserSelection); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_PPP_SELECTION_H_ + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_widget.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_widget.cc new file mode 100644 index 0000000..27ea033 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_widget.cc @@ -0,0 +1,54 @@ +// 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_widget.h" + +// Include file order cannot be observed because ppp_instance declares a +// structure return type that causes an error on Windows. +// TODO(sehr, brettw): fix the return types and include order in PPAPI. +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_rect.h" +#include "ppapi/c/pp_resource.h" +#include "srpcgen/ppp_rpc.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/ppapi_proxy/browser_ppp.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" + +namespace ppapi_proxy { + +namespace { + +const nacl_abi_size_t kPPRectBytes = + static_cast<nacl_abi_size_t>(sizeof(PP_Rect)); + +void Invalidate(PP_Instance instance, + PP_Resource widget, + const struct PP_Rect* dirty_rect) { + DebugPrintf("PPP_Widget_Dev::Invalidate: instance=%"NACL_PRIu32"\n", + instance); + + NaClSrpcError srpc_result = + PppWidgetRpcClient::PPP_Widget_Invalidate( + GetMainSrpcChannel(instance), + instance, + widget, + kPPRectBytes, + reinterpret_cast<char*>(const_cast<struct PP_Rect*>(dirty_rect))); + + DebugPrintf("PPP_Widget_Dev::Invalidate: %s\n", + NaClSrpcErrorString(srpc_result)); +} + +} // namespace + +const PPP_Widget_Dev* BrowserWidget::GetInterface() { + static const PPP_Widget_Dev widget_interface = { + Invalidate + }; + return &widget_interface; +} + +} // namespace ppapi_proxy + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_widget.h b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_widget.h new file mode 100644 index 0000000..facbb0d --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_widget.h @@ -0,0 +1,27 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_PPP_WIDGET_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_PPP_WIDGET_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "ppapi/c/dev/ppp_widget_dev.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/pp_var.h" + +namespace ppapi_proxy { + +// Implements the trusted side of the PPP_Widget_Dev interface. +class BrowserWidget { + public: + static const PPP_Widget_Dev* GetInterface(); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(BrowserWidget); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_PPP_WIDGET_H_ + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_zoom.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_zoom.cc new file mode 100644 index 0000000..bab126d --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_zoom.cc @@ -0,0 +1,46 @@ +// 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_zoom.h" + +// Include file order cannot be observed because ppp_instance declares a +// structure return type that causes an error on Windows. +// TODO(sehr, brettw): fix the return types and include order in PPAPI. +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_resource.h" +#include "srpcgen/ppp_rpc.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/ppapi_proxy/browser_ppp.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" + +namespace ppapi_proxy { + +namespace { + +void Zoom(PP_Instance instance, + double factor, + PP_Bool text_only) { + DebugPrintf("PPP_Zoom::Zoom: instance=%"NACL_PRIu32"\n", instance); + + NaClSrpcError srpc_result = PppZoomRpcClient::PPP_Zoom_Zoom( + GetMainSrpcChannel(instance), + instance, + factor, + static_cast<int32_t>(text_only)); + + DebugPrintf("PPP_Zoom::Zoom: %s\n", NaClSrpcErrorString(srpc_result)); +} + +} // namespace + +const PPP_Zoom_Dev* BrowserZoom::GetInterface() { + static const PPP_Zoom_Dev zoom_interface = { + Zoom + }; + return &zoom_interface; +} + +} // namespace ppapi_proxy + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_zoom.h b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_zoom.h new file mode 100644 index 0000000..de9bc03 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp_zoom.h @@ -0,0 +1,27 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_PPP_ZOOM_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_PPP_ZOOM_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "ppapi/c/dev/ppp_zoom_dev.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/pp_var.h" + +namespace ppapi_proxy { + +// Implements the trusted side of the PPP_Zoom_Dev interface. +class BrowserZoom { + public: + static const PPP_Zoom_Dev* GetInterface(); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(BrowserZoom); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_BROWSER_PPP_ZOOM_H_ + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_upcall.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_upcall.cc new file mode 100644 index 0000000..44d2b03 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_upcall.cc @@ -0,0 +1,91 @@ +// Copyright (c) 2010 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. +// +// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING +// +// This is an early draft of background thread support. +// Until it is complete, we assume that all functions proxy functions +// (but CallOnMainThread) are called on the main thread. +// +// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING +// +// Support for "upcalls" -- RPCs to the browser that are done from other than +// the main thread. These calls are synchronized by the ppapi_proxy library +// at the plugin end. + +#include "native_client/src/shared/ppapi_proxy/browser_upcall.h" + +#include <new> + +#include "native_client/src/include/portability.h" +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/shared/platform/nacl_threads.h" +#include "native_client/src/shared/ppapi_proxy/browser_callback.h" +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "native_client/src/trusted/desc/nacl_desc_wrapper.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/ppb_core.h" +#include "srpcgen/upcall.h" + +using nacl::DescWrapper; +using nacl::DescWrapperFactory; + +namespace { + +// Structure for passing information to the thread. Shares ownership of +// the descriptor with the creating routine. This allows passing ownership +// to the upcall thread. +struct UpcallInfo { + nacl::scoped_ptr<DescWrapper> wrapper; + NaClSrpcChannel* channel; +}; + +void WINAPI UpcallThread(void* arg) { + // The memory for info was allocated on the creating (browser UI) thread, + // but ownership was conferred to the upcall thread for deletion. + nacl::scoped_ptr<UpcallInfo> info(reinterpret_cast<UpcallInfo*>(arg)); + NaClSrpcServerLoop(info->wrapper->desc(), + PpbUpcalls::srpc_methods, + info->channel); +} + +} // namespace + +namespace ppapi_proxy { + +DescWrapper* BrowserUpcall::Start(struct NaClThread* nacl_thread, + NaClSrpcChannel* upcall_channel) { + // Create a socket pair for the upcall server. + DescWrapperFactory factory; + DescWrapper* pair[2] = { NULL, NULL }; + if (factory.MakeSocketPair(pair)) { + return NULL; + } + nacl::scoped_ptr<DescWrapper> browser_end(pair[0]); + nacl::scoped_ptr<DescWrapper> plugin_end(pair[1]); + // Create an info node to pass to the thread. + nacl::scoped_ptr<UpcallInfo> info(new UpcallInfo); + info->wrapper.reset(browser_end.get()); + info->channel = upcall_channel; + // On success, info took ownership of browser_end. + browser_end.release(); + // Create a thread and an SRPC "upcall" server. + const int kThreadStackSize = 128 * 1024; + if (!NaClThreadCreateJoinable(nacl_thread, + UpcallThread, + info.get(), + kThreadStackSize)) { + return NULL; + } + // On successful thread creation, ownership of info passes to the thread. + info.release(); + // On successful return, the caller gets the plugin_end of the socketpair. + return plugin_end.release(); +} + +} // namespace ppapi_proxy diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_upcall.h b/ppapi/native_client/src/shared/ppapi_proxy/browser_upcall.h new file mode 100644 index 0000000..ad9a5b0 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_upcall.h @@ -0,0 +1,42 @@ +// Copyright (c) 2010 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. +// +// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING +// +// This is an early draft of background thread support. +// Until it is complete, we assume that all functions proxy functions +// (but CallOnMainThread) are called on the main thread. +// +// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING +// +// Support for "upcalls" -- RPCs to the browser that are done from other than +// the PPAPI main thread. These calls are synchronized by the ppapi_proxy +// library at the plugin end. + +#include "native_client/src/include/portability.h" + +struct NaClSrpcChannel; +struct NaClThread; + +namespace nacl { +class DescWrapper; +} // namespace nacl + +namespace ppapi_proxy { + +class BrowserUpcall { + public: + // If successful, creates the listener thread in the browser that will handle + // upcalls and returns the plugin end of the upcall channel. The caller + // takes ownership of this descriptor. If either thread or socket creation + // fails, this method returns NULL. + // The thread's state is maintained by nacl_thread. Upcall processing may + // cause rpcs to be performed on main_channel (e.g., CallOnMainThread), + // so the interface takes main_channel, but the upcall thread does not have + // ownership. + static nacl::DescWrapper* Start(NaClThread* nacl_thread, + NaClSrpcChannel* main_channel); +}; + +} // namespace ppapi_proxy diff --git a/ppapi/native_client/src/shared/ppapi_proxy/build.scons b/ppapi/native_client/src/shared/ppapi_proxy/build.scons new file mode 100644 index 0000000..3d592a9 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/build.scons @@ -0,0 +1,168 @@ +# -*- python -*- +# Copyright 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. + +import os + +Import('env') + +# To get generated include files. +env.Append(CPPPATH= + ['${SOURCE_ROOT}/native_client/src/shared/ppapi_proxy/trusted']) + +if env.Bit('linux'): + env.Append( + CCFLAGS=['-fPIC', '-Wno-long-long',], + # Catch unresolved symbols in libraries. + LINKFLAGS=['-Wl,-z,defs'], + ) + +if env.Bit('mac'): + env.Append( + CCFLAGS=['-Wno-long-long'], + CPPDEFINES = [ ['TARGET_API_MAC_CARBON', '1'], 'USE_SYSTEM_CONSOLE', ], + FRAMEWORKS = ['Carbon'], + ) + +if env.Bit('windows'): + env.Append( + CPPDEFINES = ['WIN32', '_WINDOWS'], + ) + + +# The PPAPI RPCs are specified abstractly via .srpc files. +# Once a .srpc file is added to the TrustedSrpc rules below, the low-level +# server/client proxies and stubs can be generated automatically using +# scons --mode=opt-linux/mac/win srpcgen +# scons --mode=dbg-linux/mac/win sprcgen +# The .cc files are written to ./ and .h files - to ./trusted/srpcgen/. +# The generated files must be committed when changes are made to .srpc files. + +env.TrustedSrpc(is_client=True, + srpc_files=['completion_callback.srpc', + 'ppp.srpc', + 'ppp_audio.srpc', + 'ppp_find.srpc', + 'ppp_input_event.srpc', + 'ppp_instance.srpc', + 'ppp_messaging.srpc', + 'ppp_printing.srpc', + 'ppp_scrollbar.srpc', + 'ppp_selection.srpc', + 'ppp_widget.srpc', + 'ppp_zoom.srpc', + ], + name='PppRpcs', + h_file='ppp_rpc.h', + cc_file='ppp_rpc_client.cc', + guard='GEN_PPAPI_PROXY_PPP_RPC_H_') + +env.TrustedSrpc(is_client=False, + srpc_files=['nacl_file.srpc', + 'ppb.srpc', + 'ppb_audio.srpc', + 'ppb_audio_config.srpc', + 'ppb_core.srpc', + 'ppb_cursor_control.srpc', + 'ppb_file_io.srpc', + 'ppb_file_ref.srpc', + 'ppb_file_system.srpc', + 'ppb_find.srpc', + 'ppb_font.srpc', + 'ppb_graphics_2d.srpc', + 'ppb_graphics_3d.srpc', + 'ppb_image_data.srpc', + 'ppb_input_event.srpc', + 'ppb_instance.srpc', + 'ppb_messaging.srpc', + 'ppb_pdf.srpc', + 'ppb_scrollbar.srpc', + 'ppb_testing.srpc', + 'ppb_url_loader.srpc', + 'ppb_url_request_info.srpc', + 'ppb_url_response_info.srpc', + 'ppb_widget.srpc', + 'ppb_zoom.srpc', + ], + name='PpbRpcs', + h_file='ppb_rpc.h', + cc_file='ppb_rpc_server.cc', + guard='GEN_PPAPI_PROXY_PPB_RPC_H_') + +env.TrustedSrpc(is_client=False, + srpc_files=['upcall.srpc'], + name='PpbUpcalls', + h_file='upcall.h', + cc_file='upcall_server.cc', + guard='GEN_PPAPI_PROXY_UPCALL_H_') + + +common_obj = env.DualObject(['utility.cc']) + +env.DualLibrary('ppapi_browser', + ['browser_callback.cc', + 'browser_globals.cc', + 'browser_nacl_file_rpc_server.cc', + 'browser_ppb_audio_rpc_server.cc', + 'browser_ppb_audio_config_rpc_server.cc', + 'browser_ppb_core_rpc_server.cc', + 'browser_ppb_cursor_control_rpc_server.cc', + 'browser_ppb_file_io_rpc_server.cc', + 'browser_ppb_file_ref_rpc_server.cc', + 'browser_ppb_file_system_rpc_server.cc', + 'browser_ppb_find_rpc_server.cc', + 'browser_ppb_font_rpc_server.cc', + 'browser_ppb_graphics_2d_rpc_server.cc', + 'browser_ppb_graphics_3d_rpc_server.cc', + 'browser_ppb_image_data_rpc_server.cc', + 'browser_ppb_input_event_rpc_server.cc', + 'browser_ppb_instance_rpc_server.cc', + 'browser_ppb_messaging_rpc_server.cc', + 'browser_ppb_pdf_rpc_server.cc', + 'browser_ppb_rpc_server.cc', + 'browser_ppb_scrollbar_rpc_server.cc', + 'browser_ppb_testing_rpc_server.cc', + 'browser_ppb_url_loader_rpc_server.cc', + 'browser_ppb_url_request_info_rpc_server.cc', + 'browser_ppb_url_response_info_rpc_server.cc', + 'browser_ppb_widget_rpc_server.cc', + 'browser_ppb_zoom_rpc_server.cc', + 'browser_ppp_find.cc', + 'browser_ppp_input_event.cc', + 'browser_ppp_instance.cc', + 'browser_ppp_messaging.cc', + 'browser_ppp_printing.cc', + 'browser_ppp_scrollbar.cc', + 'browser_ppp_selection.cc', + 'browser_ppp_widget.cc', + 'browser_ppp_zoom.cc', + 'browser_ppp.cc', + 'browser_upcall.cc', + 'input_event_data.cc', + 'object_serialize.cc', + # Autogenerated files + 'ppb_rpc_server.cc', + 'ppp_rpc_client.cc', + 'upcall_server.cc', + common_obj,]) + +# Do a recursive diff of all files found in the first source directory against +# all the checked in versions of the files +node = env.CommandTest( + 'srpc_diff.out', + command=['${PYTHON}', '${SOURCE_ROOT}/native_client/tools/diff.py', '-arv', + '${TARGET_ROOT}/srpcgen/src', + '${SOURCE_ROOT}/native_client/src']) + +# Add a dependency on the 'srpcdif' alias for the previous command +env.Depends(node, Alias('srpcdif')) + +# Create an alias for the command and add it to the standard small test. +# This test verifies that the checked in SRPC generated files are +# actually up to date. We ignore ARM which generates false negatives. +# This is okay, since all try/builds should reproduce the same result +# this is a check on what is in source control, and generated files are +# platform independent. +if not env.Bit('target_arm'): + env.AddNodeToTestSuite(node, ['small_tests'], 'run_srpcgen_test') diff --git a/ppapi/native_client/src/shared/ppapi_proxy/command_buffer_nacl.cc b/ppapi/native_client/src/shared/ppapi_proxy/command_buffer_nacl.cc new file mode 100644 index 0000000..71bf3fa --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/command_buffer_nacl.cc @@ -0,0 +1,205 @@ +// 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/command_buffer_nacl.h" + +#include <sys/mman.h> +#include "gpu/command_buffer/common/logging.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/ppb_core.h" + +#include "srpcgen/ppb_rpc.h" + +using ppapi_proxy::DebugPrintf; + +CommandBufferNacl::CommandBufferNacl(PP_Resource graphics_3d, + const PPB_Core* iface_core) + : graphics_3d_(graphics_3d), iface_core_(iface_core) { + iface_core_->AddRefResource(graphics_3d_); +} + +CommandBufferNacl::~CommandBufferNacl() { + iface_core_->ReleaseResource(graphics_3d_); +} + +bool CommandBufferNacl::Initialize(int32 size) { + DebugPrintf("CommandBufferNacl::Initialize\n"); + int32_t success; + NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel(); + NaClSrpcError retval = + PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_InitCommandBuffer( + channel, graphics_3d_, size, &success); + DebugPrintf("CommandBufferNaCl::Initialize returned success=%s\n", + (PP_TRUE == success) ? "TRUE" : "FALSE"); + return NACL_SRPC_RESULT_OK == retval && PP_TRUE == success; +} + +gpu::Buffer CommandBufferNacl::GetRingBuffer() { + DebugPrintf("CommandBufferNacl::GetRingBuffer\n"); + if (!buffer_.ptr) { + DebugPrintf("CommandBufferNacl::GetRingBuffer: Fetching\n"); + int shm_handle = -1; + int32_t shm_size = 0; + + NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel(); + NaClSrpcError retval = + PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_GetRingBuffer( + channel, graphics_3d_, &shm_handle, &shm_size); + if (NACL_SRPC_RESULT_OK != retval) { + shm_handle = -1; + } + buffer_ = BufferFromShm(shm_handle, shm_size); + } + + return buffer_; +} + +gpu::CommandBuffer::State CommandBufferNacl::GetState() { + DebugPrintf("CommandBufferNacl::GetState\n"); + PP_Graphics3DTrustedState state; + nacl_abi_size_t state_size = static_cast<nacl_abi_size_t>(sizeof(state)); + + NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel(); + NaClSrpcError retval = + PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_GetState( + channel, graphics_3d_, &state_size, reinterpret_cast<char*>(&state)); + if (NACL_SRPC_RESULT_OK != retval + || state_size != static_cast<nacl_abi_size_t>(sizeof(state))) { + return ErrorGpuState(); + } + + last_state_ = PpapiToGpuState(state); + return last_state_; +} + +gpu::CommandBuffer::State CommandBufferNacl::GetLastState() { + return last_state_; +} + +void CommandBufferNacl::Flush(int32 put_offset) { + DebugPrintf("CommandBufferNacl::Flush\n"); + NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel(); + PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_Flush( + channel, graphics_3d_, put_offset); +} + +gpu::CommandBuffer::State CommandBufferNacl::FlushSync(int32 put_offset, + int32 last_known_get) { + DebugPrintf("CommandBufferNacl::FlushSync\n"); + PP_Graphics3DTrustedState state; + nacl_abi_size_t state_size = static_cast<nacl_abi_size_t>(sizeof(state)); + + NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel(); + NaClSrpcError retval = + PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_FlushSync( + channel, + graphics_3d_, + put_offset, + &state_size, + reinterpret_cast<char*>(&state)); + if (NACL_SRPC_RESULT_OK != retval + || state_size != static_cast<nacl_abi_size_t>(sizeof(state))) { + return ErrorGpuState(); + } + + last_state_ = PpapiToGpuState(state); + return last_state_; +} + +void CommandBufferNacl::SetGetOffset(int32 get_offset) { + DebugPrintf("CommandBufferNacl::SetGetOffset\n"); + // Not implemented by proxy. + GPU_NOTREACHED(); +} + +int32 CommandBufferNacl::CreateTransferBuffer(size_t size, int32 id_request) { + DebugPrintf("CommandBufferNacl::CreateTransferBuffer\n"); + int32_t id; + + NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel(); + NaClSrpcError retval = + PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_CreateTransferBuffer( + channel, graphics_3d_, size, id_request, &id); + if (NACL_SRPC_RESULT_OK != retval) + return 0; + + return id; +} + +void CommandBufferNacl::DestroyTransferBuffer(int32 id) { + DebugPrintf("CommandBufferNacl::DestroyTransferBuffer\n"); + NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel(); + PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_DestroyTransferBuffer( + channel, graphics_3d_, id); +} + +gpu::Buffer CommandBufferNacl::GetTransferBuffer(int32 id) { + DebugPrintf("CommandBufferNacl::GetTransferBuffer\n"); + int shm_handle; + int32_t shm_size; + + NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel(); + NaClSrpcError retval = + PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_GetTransferBuffer( + channel, graphics_3d_, id, &shm_handle, &shm_size); + if (NACL_SRPC_RESULT_OK != retval) { + return BufferFromShm(-1, 0); + } + return BufferFromShm(shm_handle, shm_size); +} + +void CommandBufferNacl::SetToken(int32 token) { + DebugPrintf("CommandBufferNacl::SetToken\n"); + // Not implemented by proxy. + GPU_NOTREACHED(); +} + +void CommandBufferNacl::SetParseError( + gpu::error::Error error) { + DebugPrintf("CommandBufferNacl::SetParseError\n"); + // Not implemented by proxy. + GPU_NOTREACHED(); +} + +void CommandBufferNacl::SetContextLostReason(gpu::error::ContextLostReason) { + // Not implemented by proxy. + GPU_NOTREACHED(); +} + +// static +gpu::Buffer CommandBufferNacl::BufferFromShm(int shm_handle, + uint32_t shm_size) { + gpu::Buffer buffer; + buffer.ptr = mmap(0, + shm_size, + PROT_READ | PROT_WRITE, + MAP_SHARED, + shm_handle, + 0); + // TODO(neb): Close the fd now that it's mapped. + // TODO(neb): Unmap ring & transfer buffers in the destructor. + if (NULL != buffer.ptr) + buffer.size = shm_size; + return buffer; +} + +// static +gpu::CommandBuffer::State CommandBufferNacl::ErrorGpuState() { + gpu::CommandBuffer::State state; + state.error = gpu::error::kGenericError; + return state; +} + +// static +gpu::CommandBuffer::State CommandBufferNacl::PpapiToGpuState( + PP_Graphics3DTrustedState s) { + gpu::CommandBuffer::State state; + state.num_entries = s.num_entries; + state.get_offset = s.get_offset; + state.put_offset = s.put_offset; + state.token = s.token; + state.error = static_cast<gpu::error::Error>(s.error); + return state; +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/command_buffer_nacl.h b/ppapi/native_client/src/shared/ppapi_proxy/command_buffer_nacl.h new file mode 100644 index 0000000..0b0dd6a --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/command_buffer_nacl.h @@ -0,0 +1,60 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_COMMAND_BUFFER_NACL_H +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_COMMAND_BUFFER_NACL_H + +#include "gpu/command_buffer/common/command_buffer.h" +#include "ppapi/c/dev/pp_graphics_3d_dev.h" +#include "ppapi/c/dev/ppb_graphics_3d_trusted_dev.h" +#include "ppapi/c/pp_resource.h" + +struct PPB_Core; + +// A CommandBuffer proxy implementation that uses trusted PPAPI interface to +// access a CommandBuffer. + +class CommandBufferNacl : public gpu::CommandBuffer { + public: + // This class will addref the graphics 3d resource using the core interface. + CommandBufferNacl(PP_Resource graphics_3d, const PPB_Core* iface_core); + virtual ~CommandBufferNacl(); + + // CommandBuffer implementation. + virtual bool Initialize(int32 size); + virtual bool Initialize(base::SharedMemory* buffer, int32 size) { + // TODO(neb): support for nacl if neccessary + return false; + } + virtual gpu::Buffer GetRingBuffer(); + virtual State GetState(); + virtual State GetLastState(); + virtual void Flush(int32 put_offset); + virtual State FlushSync(int32 put_offset, int32 last_known_get); + virtual void SetGetOffset(int32 get_offset); + virtual int32 CreateTransferBuffer(size_t size, int32 id_request); + virtual int32 RegisterTransferBuffer(base::SharedMemory* buffer, + size_t size, + int32 id_request) { + // TODO(neb): support for nacl if neccessary + return -1; + } + virtual void DestroyTransferBuffer(int32 id); + virtual gpu::Buffer GetTransferBuffer(int32 handle); + virtual void SetToken(int32 token); + virtual void SetParseError(gpu::error::Error error); + virtual void SetContextLostReason(gpu::error::ContextLostReason); + + private: + PP_Resource graphics_3d_; + const PPB_Core* iface_core_; + gpu::Buffer buffer_; + State last_state_; + + static gpu::CommandBuffer::State PpapiToGpuState(PP_Graphics3DTrustedState s); + static gpu::CommandBuffer::State ErrorGpuState(); + static gpu::Buffer BufferFromShm(int shm_handle, uint32_t shm_size); +}; + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_COMMAND_BUFFER_NACL_H diff --git a/ppapi/native_client/src/shared/ppapi_proxy/completion_callback.srpc b/ppapi/native_client/src/shared/ppapi_proxy/completion_callback.srpc new file mode 100644 index 0000000..07cf946 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/completion_callback.srpc @@ -0,0 +1,17 @@ +# Copyright (c) 2010 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. + +# RPC method that supports invocation of plugin-side callbacks from the browser. +{ + 'name': 'CompletionCallbackRpc', + 'rpcs': [ + {'name': 'RunCompletionCallback', + 'inputs': [['callback_id', 'int32_t'], + ['result', 'int32_t'], + ['read_buffer', 'char[]' ], + ], + 'outputs': [] + }, + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/input_event_data.cc b/ppapi/native_client/src/shared/ppapi_proxy/input_event_data.cc new file mode 100644 index 0000000..d94ad24 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/input_event_data.cc @@ -0,0 +1,25 @@ +// Copyright 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/input_event_data.h" + +namespace ppapi_proxy { + +InputEventData::InputEventData() + : event_type(PP_INPUTEVENT_TYPE_UNDEFINED), + event_modifiers(0), + event_time_stamp(0.0), + mouse_button(PP_INPUTEVENT_MOUSEBUTTON_NONE), + mouse_click_count(0), + mouse_position(PP_MakePoint(0, 0)), + wheel_delta(PP_MakeFloatPoint(0.0f, 0.0f)), + wheel_ticks(PP_MakeFloatPoint(0.0f, 0.0f)), + wheel_scroll_by_page(PP_FALSE), + key_code(0) { +} + +InputEventData::~InputEventData() { +} + +} // namespace ppapi_proxy diff --git a/ppapi/native_client/src/shared/ppapi_proxy/input_event_data.h b/ppapi/native_client/src/shared/ppapi_proxy/input_event_data.h new file mode 100644 index 0000000..325d3d6 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/input_event_data.h @@ -0,0 +1,45 @@ +// Copyright 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_INPUT_EVENT_DATA_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_INPUT_EVENT_DATA_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_macros.h" +#include "ppapi/c/pp_rect.h" +#include "ppapi/c/ppb_input_event.h" + +namespace ppapi_proxy { + +// The data for a single input event. +struct InputEventData { + InputEventData(); + ~InputEventData(); + + PP_InputEvent_Type event_type; + uint32_t event_modifiers; + PP_TimeTicks event_time_stamp; + + PP_InputEvent_MouseButton mouse_button; + int32_t mouse_click_count; + PP_Point mouse_position; + + PP_FloatPoint wheel_delta; + PP_FloatPoint wheel_ticks; + PP_Bool wheel_scroll_by_page; + + uint32_t key_code; +}; +// Make sure that the size is consistent across platforms, so the alignment is +// consistent. Note the fields above are carefully ordered to make sure it is +// consistent. New fields may require some adjustment to keep a consistent size +// and alignment. TODO(dmichael): This is only required because we don't pickle +// the type. As a short-cut, we memcpy it instead. It would be cleaner to +// pickle this struct. +PP_COMPILE_ASSERT_SIZE_IN_BYTES(InputEventData, 56); + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_INPUT_EVENT_DATA_H_ diff --git a/ppapi/native_client/src/shared/ppapi_proxy/nacl.scons b/ppapi/native_client/src/shared/ppapi_proxy/nacl.scons new file mode 100644 index 0000000..4b7a433 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/nacl.scons @@ -0,0 +1,177 @@ +# -*- python -*- +# 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. + +Import('env') + +# Underlay $SOURCE_ROOT/gpu in this directory. +Dir('.').addRepository(Dir('#/../gpu')) + +# To enable getting the generated include files and sources and also common and +# client GPU command buffer sources. +env.Append(CPPPATH= + ['${SOURCE_ROOT}/native_client/src/shared/ppapi_proxy/untrusted', + '$SOURCE_ROOT/gpu']) + +env.Append(CPPDEFINES=['XP_UNIX']) +env.FilterOut(CCFLAGS=['-Wswitch-enum']) +env.Append(CCFLAGS=['-Wno-long-long']) + +# The PPAPI RPCs are specified abstractly via .srpc files. +# Once a .srpc file is added to the UntrustedSrpc rules below, the low-level +# server/client proxies and stubs can be generated automatically using +# scons srpcgen +# The .cc files are written to ./ and .h files - to ./untrusted/srpcgen/. +# The generated files must be committed when changes are made to .srpc files. + +env.UntrustedSrpc(is_client=False, + srpc_files=['completion_callback.srpc', + 'ppp.srpc', + 'ppp_audio.srpc', + 'ppp_find.srpc', + 'ppp_input_event.srpc', + 'ppp_instance.srpc', + 'ppp_messaging.srpc', + 'ppp_printing.srpc', + 'ppp_scrollbar.srpc', + 'ppp_selection.srpc', + 'ppp_widget.srpc', + 'ppp_zoom.srpc', + ], + name='PppRpcs', + h_file='ppp_rpc.h', + cc_file='ppp_rpc_server.cc', + guard='GEN_PPAPI_PROXY_PPP_RPC_H_') + +env.UntrustedSrpc(is_client=True, + srpc_files=['nacl_file.srpc', + 'ppb.srpc', + 'ppb_audio.srpc', + 'ppb_audio_config.srpc', + 'ppb_core.srpc', + 'ppb_cursor_control.srpc', + 'ppb_file_io.srpc', + 'ppb_file_ref.srpc', + 'ppb_file_system.srpc', + 'ppb_find.srpc', + 'ppb_font.srpc', + 'ppb_graphics_2d.srpc', + 'ppb_graphics_3d.srpc', + 'ppb_image_data.srpc', + 'ppb_input_event.srpc', + 'ppb_instance.srpc', + 'ppb_messaging.srpc', + 'ppb_pdf.srpc', + 'ppb_scrollbar.srpc', + 'ppb_testing.srpc', + 'ppb_url_loader.srpc', + 'ppb_url_request_info.srpc', + 'ppb_url_response_info.srpc', + 'ppb_widget.srpc', + 'ppb_zoom.srpc', + ], + name='PpbRpcs', + h_file='ppb_rpc.h', + cc_file='ppb_rpc_client.cc', + guard='GEN_PPAPI_PROXY_PPB_RPC_H_', + thread_check=True) + +env.UntrustedSrpc(is_client=True, + srpc_files=['upcall.srpc'], + name='PpbUpcalls', + h_file='upcall.h', + cc_file='upcall_client.cc', + guard='GEN_PPAPI_PROXY_UPCALL_H_') + +command_buffer_common_srcs = [ + 'command_buffer/common/cmd_buffer_common.cc', + 'command_buffer/common/gles2_cmd_format.cc', + 'command_buffer/common/gles2_cmd_utils.cc', + ] + +command_buffer_client_srcs = [ + 'command_buffer/client/cmd_buffer_helper.cc', + 'command_buffer/client/fenced_allocator.cc', + 'command_buffer/client/gles2_c_lib.cc', + 'command_buffer/client/gles2_cmd_helper.cc', + 'command_buffer/client/gles2_implementation.cc', + 'command_buffer/client/program_info_manager.cc', + 'command_buffer/client/gles2_lib.cc', + 'command_buffer/client/mapped_memory.cc', + 'command_buffer/client/ring_buffer.cc', + 'command_buffer/common/id_allocator.cc', + ] + +command_buffer_srcs = command_buffer_common_srcs + command_buffer_client_srcs; + +libppruntime = env.NaClSdkLibrary( + 'libppruntime', + ['command_buffer_nacl.cc', + 'input_event_data.cc', + 'object_serialize.cc', + 'plugin_callback.cc', + 'plugin_globals.cc', + 'plugin_instance_data.cc', + 'plugin_main.cc', + 'plugin_nacl_file.cc', + 'plugin_opengles.cc', + 'plugin_ppb.cc', + 'plugin_ppb_audio.cc', + 'plugin_ppb_audio_config.cc', + 'plugin_ppb_buffer.cc', + 'plugin_ppb_core.cc', + 'plugin_ppb_cursor_control.cc', + 'plugin_ppb_file_io.cc', + 'plugin_ppb_file_system.cc', + 'plugin_ppb_file_ref.cc', + 'plugin_ppb_find.cc', + 'plugin_ppb_font.cc', + 'plugin_ppb_graphics_2d.cc', + 'plugin_ppb_graphics_3d.cc', + 'plugin_ppb_image_data.cc', + 'plugin_ppb_input_event.cc', + 'plugin_ppb_instance.cc', + 'plugin_ppb_memory.cc', + 'plugin_ppb_messaging.cc', + 'plugin_ppb_pdf.cc', + 'plugin_ppb_scrollbar.cc', + 'plugin_ppb_testing.cc', + 'plugin_ppb_url_loader.cc', + 'plugin_ppb_url_request_info.cc', + 'plugin_ppb_url_response_info.cc', + 'plugin_ppb_var.cc', + 'plugin_ppb_widget.cc', + 'plugin_ppb_zoom.cc', + 'plugin_ppp_find_rpc_server.cc', + 'plugin_ppp_input_event_rpc_server.cc', + 'plugin_ppp_instance_rpc_server.cc', + 'plugin_ppp_messaging_rpc_server.cc', + 'plugin_ppp_printing_rpc_server.cc', + 'plugin_ppp_scrollbar_rpc_server.cc', + 'plugin_ppp_selection_rpc_server.cc', + 'plugin_ppp_widget_rpc_server.cc', + 'plugin_ppp_zoom_rpc_server.cc', + 'plugin_ppp_rpc_server.cc', + 'plugin_resource.cc', + 'plugin_resource_tracker.cc', + 'plugin_threading.cc', + 'plugin_upcall.cc', + 'proxy_var.cc', + 'proxy_var_cache.cc', + 'utility.cc', + # Autogenerated files + 'ppp_rpc_server.cc', + 'ppb_rpc_client.cc', + 'upcall_client.cc'] + command_buffer_srcs, + LIBS=['pthread', + 'srpc', + 'gio', + 'platform', + ]) + +header_install = env.AddHeaderToSdk(['ppruntime.h']) +env.AddLibraryToSdk(libppruntime) + +# Clients that overload main() will use ppruntime.h. +env.Requires(libppruntime, header_install) diff --git a/ppapi/native_client/src/shared/ppapi_proxy/nacl_file.srpc b/ppapi/native_client/src/shared/ppapi_proxy/nacl_file.srpc new file mode 100644 index 0000000..2f2fe45 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/nacl_file.srpc @@ -0,0 +1,28 @@ +# 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. +# +# RPC methods used to implement nacl_file support. +# See native_client/src/untrusted/ppapi/nacl_file.h for interface details. + +{ + 'name': 'NaClFileRpc', + 'rpcs': [ + {'name': 'StreamAsFile', + 'inputs': [['instance', 'PP_Instance'], + ['url', 'string'], + ['callback_id', 'int32_t'], + ], + # No return value as the callback will always + # be invoked on success or failure. + 'outputs': [] + }, + {'name': 'GetFileDesc', + 'inputs': [['instance', 'PP_Instance'], + ['url', 'string'], + ], + 'outputs': [['file_desc', 'handle'], + ] + } + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/object_serialize.cc b/ppapi/native_client/src/shared/ppapi_proxy/object_serialize.cc new file mode 100644 index 0000000..15cc7ed --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/object_serialize.cc @@ -0,0 +1,468 @@ +/* + * 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/object_serialize.h" + +#include <limits> +#include <stdio.h> +#include <string.h> + + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/portability_process.h" +#ifdef __native_client__ +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#else +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#endif // __native_client__ +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/pp_bool.h" +#include "ppapi/c/pp_var.h" + +namespace ppapi_proxy { + +namespace { + +// A serialized string consists of a fixed minimum of 8 bytes. +static const int kStringFixedBytes = 8; +// Followed by a varying number of bytes rounded up to the nearest 8 bytes. +static const uint32_t kStringRoundBase = 8; + +} // namespace + +// The basic serialization structure. Used alone for PP_VARTYPE_VOID, +// PP_VARTYPE_NULL, and PP_VARTYPE_INT32. +struct SerializedFixed { + uint32_t type; + union { + // PP_VARTYPE_BOOLEAN uses this. + bool boolean_value; + // PP_VARTYPE_INT32 uses this. + int32_t int32_value; + // PP_VARTYPE_STRING uses this. + uint32_t string_length; + } u; + // The size of this structure should be 8 bytes on all platforms. +}; + +// The structure used for PP_VARTYPE_DOUBLE. +struct SerializedDouble { + struct SerializedFixed fixed; + double double_value; +}; + +// The structure used for PP_VARTYPE_STRING. + +struct SerializedString { + struct SerializedFixed fixed; + char string_bytes[kStringFixedBytes]; + // Any remaining characters immediately follow, and are padded out to the + // nearest multiple of kStringRoundBase bytes. +}; + +// TODO(sehr): Add a more general compile time assertion package elsewhere. +#define ASSERT_TYPE_SIZE(struct_name, struct_size) \ + int struct_name##_size_should_be_##struct_size[ \ + sizeof(struct_name) == struct_size ? 1 : 0] + +// Check the wire format sizes for the PP_Var subtypes. +ASSERT_TYPE_SIZE(SerializedFixed, 8); +ASSERT_TYPE_SIZE(SerializedDouble, 16); +ASSERT_TYPE_SIZE(SerializedString, 16); + +// +// We currently use offsetof to find the start of string storage. +// This avoids the (never seen) case where the compiler inserts in +// padding between the struct SerializedFixed fixed header and the +// actual payload value in the double, string, and object +// serialization variants. +// +// Untrusted arm toolchain defines an offsetof in stddef.h, so we have +// to prefix. +// +#define NACL_OFFSETOF(pod_t, member) \ + (static_cast<size_t>(reinterpret_cast<uintptr_t>(&((pod_t *) NULL)->member))) + +namespace { + +// Adding value1 and value2 would overflow a uint32_t. +bool AddWouldOverflow(size_t value1, size_t value2) { + if (value1 > std::numeric_limits<size_t>::max() - value2) { + return true; + } + size_t sum = value1 + value2; + return sum > std::numeric_limits<uint32_t>::max(); +} + +uint32_t RoundedStringBytes(uint32_t string_length) { + // Compute the string length, padded to the nearest multiple of 8. + if (AddWouldOverflow(string_length, kStringRoundBase - 1)) { + return std::numeric_limits<uint32_t>::max(); + } + return (string_length + (kStringRoundBase - 1)) & ~(kStringRoundBase - 1); +} + +uint32_t PpVarSize(const PP_Var& var) { + switch (var.type) { + case PP_VARTYPE_UNDEFINED: + case PP_VARTYPE_NULL: + case PP_VARTYPE_BOOL: + case PP_VARTYPE_INT32: + return sizeof(SerializedFixed); + case PP_VARTYPE_DOUBLE: + return sizeof(SerializedDouble); + case PP_VARTYPE_STRING: { + uint32_t string_length; + (void) PPBVarInterface()->VarToUtf8(var, &string_length); + string_length = RoundedStringBytes(string_length); + if (std::numeric_limits<uint32_t>::max() == string_length || + AddWouldOverflow(string_length, + NACL_OFFSETOF(SerializedString, string_bytes))) { + // Adding the length to the fixed portion would overflow. + return 0; + } + return static_cast<uint32_t>(NACL_OFFSETOF(SerializedString, string_bytes) + + string_length); + break; + } + case PP_VARTYPE_OBJECT: + case PP_VARTYPE_ARRAY: + case PP_VARTYPE_DICTIONARY: + NACL_NOTREACHED(); + break; + } + // Unrecognized type. + return 0; +} + +uint32_t PpVarVectorSize(const PP_Var* vars, uint32_t argc) { + size_t size = 0; + + for (uint32_t i = 0; i < argc; ++i) { + size_t element_size = PpVarSize(vars[i]); + + if (0 == element_size || AddWouldOverflow(size, element_size)) { + // Overflow. + return 0; + } + size += element_size; + } + return static_cast<uint32_t>(size); +} + +bool SerializePpVar(const PP_Var* vars, + uint32_t argc, + char* bytes, + uint32_t length) { + size_t offset = 0; + + for (uint32_t i = 0; i < argc; ++i) { + size_t element_size = PpVarSize(vars[i]); + if (0 == element_size || AddWouldOverflow(offset, element_size)) { + // Overflow. + return false; + } + if (offset + element_size > length) { + // Not enough bytes to put the requested number of PP_Vars. + return false; + } + + char* p = bytes + offset; + SerializedFixed* s = reinterpret_cast<SerializedFixed*>(p); + s->type = static_cast<uint32_t>(vars[i].type); + // Set the rest of SerializedFixed to 0, in case the following serialization + // leaves some of it unchanged. + s->u.int32_value = 0; + + switch (vars[i].type) { + case PP_VARTYPE_UNDEFINED: + case PP_VARTYPE_NULL: + element_size = sizeof(SerializedFixed); + break; + case PP_VARTYPE_BOOL: + s->u.boolean_value = static_cast<bool> + (PP_TRUE == vars[i].value.as_bool); + element_size = sizeof(SerializedFixed); + break; + case PP_VARTYPE_INT32: + s->u.int32_value = vars[i].value.as_int; + element_size = sizeof(SerializedFixed); + break; + case PP_VARTYPE_DOUBLE: { + SerializedDouble* sd = reinterpret_cast<SerializedDouble*>(p); + sd->double_value = vars[i].value.as_double; + element_size = sizeof(SerializedDouble); + break; + } + case PP_VARTYPE_STRING: { + uint32_t string_length; + const char* str = PPBVarInterface()->VarToUtf8(vars[i], &string_length); + SerializedString* ss = reinterpret_cast<SerializedString*>(p); + ss->fixed.u.string_length = string_length; + memcpy(reinterpret_cast<void*>(ss->string_bytes), + reinterpret_cast<const void*>(str), + string_length); + // Fill padding bytes with zeros. + memset(reinterpret_cast<void*>(ss->string_bytes + string_length), 0, + RoundedStringBytes(string_length) - string_length); + element_size = NACL_OFFSETOF(SerializedString, string_bytes) + + RoundedStringBytes(string_length); + break; + } + case PP_VARTYPE_OBJECT: + case PP_VARTYPE_ARRAY: + case PP_VARTYPE_DICTIONARY: + NACL_NOTREACHED(); + default: + return false; + } + offset += element_size; + } + return true; +} + + +// +// Compute how many bytes does the string object to be deserialzed use +// in the serialized format. On error, return +// std::numeric_limits<uint32_t>::max(). This means we cannot handle +// 2**32-1 byte strings. +// +uint32_t DeserializeStringSize(char* p, uint32_t length) { + // zero length strings are okay... but not shorter + if (length < NACL_OFFSETOF(SerializedString, string_bytes)) { + return std::numeric_limits<uint32_t>::max(); + } + SerializedString* ss = reinterpret_cast<SerializedString*>(p); + if (PP_VARTYPE_STRING != ss->fixed.type) { + return std::numeric_limits<uint32_t>::max(); + } + uint32_t string_length = ss->fixed.u.string_length; + string_length = RoundedStringBytes(string_length); + if (std::numeric_limits<uint32_t>::max() == string_length) { + return std::numeric_limits<uint32_t>::max(); + } + if (AddWouldOverflow(NACL_OFFSETOF(SerializedString, string_bytes), + string_length)) { + return std::numeric_limits<uint32_t>::max(); + } + uint32_t total_bytes = NACL_OFFSETOF(SerializedString, string_bytes) + + string_length; + if (total_bytes > length) { + return std::numeric_limits<uint32_t>::max(); + } + return total_bytes; +} + + +// +// Compute the number of bytes that will be consumed by the next +// object, based on its type. If there aren't enough bytes, +// std::numeric_limits<uint32_t>::max() will be returned. +// +// If element_type_ptr is non-NULL, then the next element's +// (purported) type will be filled in. Whether this occurs when there +// is an error (e.g., not enough data) is not defined, i.e., only rely +// on it when there's no error. +// +uint32_t DeserializePpVarSize(char* p, + uint32_t length, + PP_VarType* element_type_ptr) { + SerializedFixed* sfp; + if (length < sizeof *sfp) { + return std::numeric_limits<uint32_t>::max(); + } + sfp = reinterpret_cast<SerializedFixed*>(p); + uint32_t expected_element_size = 0; + // + // Setting this to zero handles the "default" case. That can occur + // because sfp->type can originate from untrusted code, and so the + // value could actually be outside of the PP_VarType enumeration + // range. If we hit one of the cases below, then + // expected_element_size will be bounded away from zero. + // + switch (static_cast<PP_VarType>(sfp->type)) { + case PP_VARTYPE_UNDEFINED: + case PP_VARTYPE_NULL: + case PP_VARTYPE_BOOL: + case PP_VARTYPE_INT32: + expected_element_size = sizeof(SerializedFixed); + break; + case PP_VARTYPE_DOUBLE: + expected_element_size = sizeof(SerializedDouble); + break; + case PP_VARTYPE_STRING: + expected_element_size = DeserializeStringSize(p, length); + if (std::numeric_limits<uint32_t>::max() == expected_element_size) { + return std::numeric_limits<uint32_t>::max(); + } + break; + // NB: No default case to trigger -Wswitch-enum, so changes to + // PP_VarType w/o corresponding changes here will cause a + // compile-time error. + case PP_VARTYPE_OBJECT: + case PP_VARTYPE_ARRAY: + case PP_VARTYPE_DICTIONARY: + NACL_NOTREACHED(); + break; + } + if (length < expected_element_size) { + return std::numeric_limits<uint32_t>::max(); + } + if (NULL != element_type_ptr) { + *element_type_ptr = static_cast<PP_VarType>(sfp->type); + } + return expected_element_size; +} + + +// +// This should be invoked only if DeserializePpVarSize succeeds, i.e., +// there are enough bytes at p. +// +bool DeserializeString(char* p, + PP_Var* var, + NaClSrpcChannel* channel) { + SerializedString* ss = reinterpret_cast<SerializedString*>(p); + uint32_t string_length = ss->fixed.u.string_length; + // VarFromUtf8 creates a buffer of size string_length using the browser-side + // memory allocation function, and copies string_length bytes from + // ss->string_bytes in to that buffer. The ref count of the returned var is + // 1. + *var = PPBVarInterface()->VarFromUtf8(LookupModuleIdForSrpcChannel(channel), + ss->string_bytes, + string_length); + return true; +} + +bool DeserializePpVar(NaClSrpcChannel* channel, + char* bytes, + uint32_t length, + PP_Var* vars, + uint32_t argc) { + char* p = bytes; + + for (uint32_t i = 0; i < argc; ++i) { + PP_VarType element_type; + uint32_t element_size = DeserializePpVarSize(p, length, &element_type); + if (std::numeric_limits<uint32_t>::max() == element_size) { + return false; + } + SerializedFixed* s = reinterpret_cast<SerializedFixed*>(p); + + vars[i].type = element_type; + switch (element_type) { + case PP_VARTYPE_UNDEFINED: + case PP_VARTYPE_NULL: + break; + case PP_VARTYPE_BOOL: + vars[i].value.as_bool = static_cast<PP_Bool>(s->u.boolean_value); + break; + case PP_VARTYPE_INT32: + vars[i].value.as_int = s->u.int32_value; + break; + case PP_VARTYPE_DOUBLE: { + SerializedDouble* sd = reinterpret_cast<SerializedDouble*>(p); + vars[i].value.as_double = sd->double_value; + break; + } + case PP_VARTYPE_STRING: + if (!DeserializeString(p, &vars[i], channel)) { + return false; + } + break; + case PP_VARTYPE_OBJECT: + case PP_VARTYPE_ARRAY: + case PP_VARTYPE_DICTIONARY: + NACL_NOTREACHED(); + default: + return false; + } + p += element_size; + length -= element_size; + } + return true; +} + +} // namespace + +bool SerializeTo(const PP_Var* var, char* bytes, uint32_t* length) { + if (bytes == NULL || length == NULL) { + return false; + } + // Compute the size of the serialized form. Zero indicates error. + uint32_t tmp_length = PpVarVectorSize(var, 1); + if (0 == tmp_length || tmp_length > *length) { + return false; + } + // Serialize the var. + if (!SerializePpVar(var, 1, bytes, tmp_length)) { + return false; + } + // Return success. + *length = tmp_length; + return true; +} + +char* Serialize(const PP_Var* vars, uint32_t argc, uint32_t* length) { + // Length needs to be set. + if (NULL == length) { + return NULL; + } + // No need to do anything if there are no vars to serialize. + if (0 == argc) { + *length = 0; + return NULL; + } + // Report an error if no vars are passed but argc > 0. + if (NULL == vars) { + return NULL; + } + // Compute the size of the buffer. Zero indicates error. + uint32_t tmp_length = PpVarVectorSize(vars, argc); + if (0 == tmp_length || tmp_length > *length) { + return NULL; + } + // Allocate the buffer, if the client didn't pass one. + char* bytes = new char[tmp_length]; + if (NULL == bytes) { + return NULL; + } + // Serialize the vars. + if (!SerializePpVar(vars, argc, bytes, tmp_length)) { + delete[] bytes; + return NULL; + } + // Return success. + *length = tmp_length; + return bytes; +} + +bool DeserializeTo(NaClSrpcChannel* channel, + char* bytes, + uint32_t length, + uint32_t argc, + PP_Var* vars) { + // Deserializing a zero-length vector is trivially done. + if (0 == argc) { + return true; + } + // Otherwise, there must be some input bytes to get from. + if (NULL == bytes || 0 == length) { + return false; + } + // And there has to be a valid address to deserialize to. + if (NULL == vars) { + return false; + } + // Read the serialized PP_Vars into the allocated memory. + if (!DeserializePpVar(channel, bytes, length, vars, argc)) { + return false; + } + return true; +} + +} // namespace ppapi_proxy diff --git a/ppapi/native_client/src/shared/ppapi_proxy/object_serialize.h b/ppapi/native_client/src/shared/ppapi_proxy/object_serialize.h new file mode 100644 index 0000000..bd8afaf --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/object_serialize.h @@ -0,0 +1,39 @@ +/* + * Copyright 2010 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. + */ + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_OBJECT_SERIALIZE_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_OBJECT_SERIALIZE_H_ + +#include "ppapi/c/pp_var.h" + +struct NaClSrpcChannel; + +namespace ppapi_proxy { + +const uint32_t kMaxVarSize = 64 * 1024; + +// Serialize one PP_Var to the location given in "bytes", using no more +// than "*length" bytes . If successful, "*length" reflects the number of +// bytes written and true is returned. Otherwise returns false. +bool SerializeTo(const PP_Var* var, char* bytes, uint32_t* length); + +// Serialize a vector of "argc" PP_Vars to a buffer to be allocated by new[]. +// If successful, the address of a buffer is returned and "*length" is set +// to the number of bytes allocated. Otherwise, NULL is returned. +char* Serialize(const PP_Var* vars, uint32_t argc, uint32_t* length); + +// Deserialize a vector "bytes" of "length" bytes containing "argc" PP_Vars +// into the vector of PP_Vars pointed to by "vars". Returns true if +// successful, or false otherwise. +bool DeserializeTo(NaClSrpcChannel* channel, + char* bytes, + uint32_t length, + uint32_t argc, + PP_Var* vars); + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_OBJECT_SERIALIZE_H_ diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_callback.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_callback.cc new file mode 100644 index 0000000..dfe0b03 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_callback.cc @@ -0,0 +1,95 @@ +// 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/plugin_callback.h" +#include <string.h> +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/pp_errors.h" +#include "srpcgen/ppp_rpc.h" + +namespace ppapi_proxy { + +int32_t MayForceCallback(PP_CompletionCallback callback, int32_t result) { + if (result == PP_OK_COMPLETIONPENDING) + return result; + + if (callback.func == NULL || + (callback.flags & PP_COMPLETIONCALLBACK_FLAG_OPTIONAL) != 0) + return result; + + PPBCoreInterface()->CallOnMainThread(0, callback, result); + return PP_OK_COMPLETIONPENDING; +} + +// Initialize static mutex used as critical section for all callback tables. +pthread_mutex_t CompletionCallbackTable::mutex_ = PTHREAD_MUTEX_INITIALIZER; + +int32_t CompletionCallbackTable::AddCallback( + const PP_CompletionCallback& callback, + void* read_buffer) { + CallbackTableCriticalSection guard; + if (callback.func == NULL) { + DebugPrintf("CompletionCallbackTable attempted to add NULL func!!\n"); + return 0; + } + int32_t callback_id = next_id_; + ++next_id_; + CallbackInfo info = { callback, read_buffer }; + table_.insert(std::pair<int32_t, CallbackInfo>(callback_id, info)); + return callback_id; +} + +int32_t CompletionCallbackTable::AddCallback( + const PP_CompletionCallback& callback) { + return AddCallback(callback, NULL); +} + +PP_CompletionCallback CompletionCallbackTable::RemoveCallback( + int32_t callback_id, void** read_buffer) { + CallbackTableCriticalSection guard; + CallbackTable::iterator it = table_.find(callback_id); + DebugPrintf("CompletionCallbackTable::RemoveCallback id: %"NACL_PRId32"\n", + callback_id); + if (table_.end() != it) { + CallbackInfo info = it->second; + table_.erase(it); + if (read_buffer != NULL) + *read_buffer = info.read_buffer; + return info.callback; + } + *read_buffer = NULL; + return PP_BlockUntilComplete(); +} + +} // namespace ppapi_proxy + +// SRPC-abstraction wrapper around a PP_CompletionCallback. +void CompletionCallbackRpcServer::RunCompletionCallback( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + int32_t callback_id, + int32_t result, + // TODO(polina): use shm for read buffer + nacl_abi_size_t read_buffer_size, char* read_buffer) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + + void* user_buffer; + PP_CompletionCallback callback = + ppapi_proxy::CompletionCallbackTable::Get()->RemoveCallback( + callback_id, &user_buffer); + if (callback.func == NULL) { + ppapi_proxy::DebugPrintf( + "CompletionCallbackRpcServer: id of %"NACL_PRId32" is NULL callback!\n", + callback_id); + return; + } + + if (user_buffer != NULL && read_buffer_size > 0) + memcpy(user_buffer, read_buffer, read_buffer_size); + PP_RunCompletionCallback(&callback, result); + + rpc->result = NACL_SRPC_RESULT_OK; +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_callback.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_callback.h new file mode 100644 index 0000000..4632ecf --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_callback.h @@ -0,0 +1,65 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_CALLBACK_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_CALLBACK_H_ + +#include <pthread.h> +#include <map> +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "ppapi/c/pp_completion_callback.h" + +namespace ppapi_proxy { + +// Skips callback invocation and returns |result| if callback function is NULL +// or PP_COMPLETIONCALLBACK_FLAG_OPTIONAL is set. Otherwise, schedules the +// callback with |result| as an argument and returns PP_OK_COMPLETIONPENDING. +int32_t MayForceCallback(PP_CompletionCallback callback, int32_t result); + +// Maintains a table of PP_CompletionCallback objects and their respective +// identifiers that can be used to retrieve the objects. +class CompletionCallbackTable { + public: + // Return a singleton instance. + static CompletionCallbackTable* Get() { + static CompletionCallbackTable table; + return &table; + } + + // Adds the given |callback| and optionally the associated |read_buffer|, + // generating and returning an identifier for it. + // If |callback| is NULL, then returns 0. + int32_t AddCallback(const PP_CompletionCallback& callback); + int32_t AddCallback(const PP_CompletionCallback& callback, void* read_buffer); + // Removes and returns the callback and optionally the associated + // |read_buffer| corresponding to the given |callback_id|. + // If no callback is found, returns a NULL callback. + PP_CompletionCallback RemoveCallback(int32_t callback_id, void** read_buffer); + + private: + // Currently implemented as singleton, so use a private constructor. + CompletionCallbackTable() : next_id_(1) { } + ~CompletionCallbackTable() { } + + struct CallbackInfo { + PP_CompletionCallback callback; + void* read_buffer; // To be used with callbacks invoked on byte reads. + }; + + typedef std::map<int32_t, CallbackInfo> CallbackTable; + CallbackTable table_; + int32_t next_id_; + + // Single static mutex used as critical section for all callback tables. + static pthread_mutex_t mutex_; + class CallbackTableCriticalSection { + public: + CallbackTableCriticalSection() { pthread_mutex_lock(&mutex_); } + ~CallbackTableCriticalSection() { pthread_mutex_unlock(&mutex_); } + }; +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_CALLBACK_H_ diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_globals.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_globals.cc new file mode 100644 index 0000000..cd018a40 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_globals.cc @@ -0,0 +1,184 @@ +// 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 <sys/nacl_imc_api.h> +#include <sys/nacl_syscalls.h> + +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/plugin_ppb_core.h" +#include "native_client/src/shared/ppapi_proxy/plugin_ppb_var.h" +#include "native_client/src/shared/ppapi_proxy/ppruntime.h" +#include "native_client/src/shared/ppapi_proxy/untrusted/srpcgen/ppp_rpc.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "native_client/src/shared/srpc/nacl_srpc.h" + + +#define NACL_SEND_FD 6 + +namespace { + +NaClSrpcChannel* main_srpc_channel; +NaClSrpcChannel* upcall_srpc_channel; +PP_Module module_id_for_plugin; +struct PP_ThreadFunctions thread_funcs; + +} // namespace + +namespace ppapi_proxy { + +const PP_Resource kInvalidResourceId = 0; + +NaClSrpcChannel* GetMainSrpcChannel() { + return main_srpc_channel; +} + +void SetMainSrpcChannel(NaClSrpcChannel* channel) { + main_srpc_channel = channel; +} + +NaClSrpcChannel* GetUpcallSrpcChannel() { + return upcall_srpc_channel; +} + +void SetUpcallSrpcChannel(NaClSrpcChannel* channel) { + upcall_srpc_channel = channel; +} + +void SetModuleIdForSrpcChannel(NaClSrpcChannel* channel, PP_Module module_id) { + module_id_for_plugin = module_id; +} + +void UnsetModuleIdForSrpcChannel(NaClSrpcChannel* channel) { + const PP_Module kInvalidModuleId = 0; + module_id_for_plugin = kInvalidModuleId; +} + +PP_Module LookupModuleIdForSrpcChannel(NaClSrpcChannel* channel) { + return module_id_for_plugin; +} + +const struct PP_ThreadFunctions* GetThreadCreator() { + return &thread_funcs; +} + +// Browser interface helpers + +const void* GetBrowserInterfaceSafe(const char* interface_name) { + const void* ppb_interface = GetBrowserInterface(interface_name); + if (ppb_interface == NULL) + DebugPrintf("PPB_GetInterface: %s not found\n", interface_name); + CHECK(ppb_interface != NULL); + return ppb_interface; +} + +const PPB_Core* PPBCoreInterface() { + return static_cast<const PPB_Core*>( + GetBrowserInterfaceSafe(PPB_CORE_INTERFACE)); +} + +const PPB_Memory_Dev* PPBMemoryInterface() { + return static_cast<const PPB_Memory_Dev*>( + GetBrowserInterfaceSafe(PPB_MEMORY_DEV_INTERFACE)); +} + +const PPB_Var* PPBVarInterface() { + return static_cast<const PPB_Var*>( + GetBrowserInterfaceSafe(PPB_VAR_INTERFACE)); +} + +// Plugin interface helpers + +const void* GetPluginInterface(const char* interface_name) { + return ::PPP_GetInterface(interface_name); +} + +const void* GetPluginInterfaceSafe(const char* interface_name) { + const void* ppp_interface = GetPluginInterface(interface_name); + if (ppp_interface == NULL) + DebugPrintf("PPP_GetInterface: %s not found\n", interface_name); + CHECK(ppp_interface != NULL); + return ppp_interface; +} + +const PPP_Find_Dev* PPPFindInterface() { + static const void* ppp = GetPluginInterfaceSafe(PPP_FIND_DEV_INTERFACE); + return static_cast<const PPP_Find_Dev*>(ppp); +} + +const PPP_InputEvent* PPPInputEventInterface() { + static const void* ppp = GetPluginInterfaceSafe(PPP_INPUT_EVENT_INTERFACE); + return static_cast<const PPP_InputEvent*>(ppp); +} + +const PPP_Instance* PPPInstanceInterface() { + static const void* ppp = GetPluginInterfaceSafe(PPP_INSTANCE_INTERFACE); + return static_cast<const PPP_Instance*>(ppp); +} + +const PPP_Messaging* PPPMessagingInterface() { + static const void* ppp = GetPluginInterfaceSafe(PPP_MESSAGING_INTERFACE); + return static_cast<const PPP_Messaging*>(ppp); +} + +const PPP_Printing_Dev* PPPPrintingInterface() { + static const void* ppp = GetPluginInterfaceSafe(PPP_PRINTING_DEV_INTERFACE); + return static_cast<const PPP_Printing_Dev*>(ppp); +} + +const PPP_Scrollbar_Dev* PPPScrollbarInterface() { + static const void* ppp = GetPluginInterfaceSafe(PPP_SCROLLBAR_DEV_INTERFACE); + return static_cast<const PPP_Scrollbar_Dev*>(ppp); +} + +const PPP_Selection_Dev* PPPSelectionInterface() { + static const void* ppp = GetPluginInterfaceSafe(PPP_SELECTION_DEV_INTERFACE); + return static_cast<const PPP_Selection_Dev*>(ppp); +} + +const PPP_Widget_Dev* PPPWidgetInterface() { + static const void* ppp = GetPluginInterfaceSafe(PPP_WIDGET_DEV_INTERFACE); + return static_cast<const PPP_Widget_Dev*>(ppp); +} + +const PPP_Zoom_Dev* PPPZoomInterface() { + static const void* ppp = GetPluginInterfaceSafe(PPP_ZOOM_DEV_INTERFACE); + return static_cast<const PPP_Zoom_Dev*>(ppp); +} + + +} // namespace ppapi_proxy + +void PpapiPluginRegisterThreadCreator( + const struct PP_ThreadFunctions* new_funcs) { + thread_funcs = *new_funcs; +} + +int IrtInit() { + // TODO(halyavin): this is needed for tests without IRT. They do not start + // in irt_entry.c where IrtInit is called. + static int initialized = 0; + if (initialized) { + return 0; + } + if (!NaClSrpcModuleInit()) { + return 1; + } + NaClLogModuleInit(); // Enable NaClLog'ing used by CHECK(). + initialized = 1; + return 0; +} + +int PpapiPluginMain() { + IrtInit(); + PpapiPluginRegisterDefaultThreadCreator(); + // Designate this as the main thread for PPB_Core::IsMainThread(). + ppapi_proxy::PluginCore::MarkMainThread(); + if (!NaClSrpcAcceptClientConnection(PppRpcs::srpc_methods)) { + return 1; + } + NaClSrpcModuleFini(); + + return 0; +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_globals.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_globals.h new file mode 100644 index 0000000..915ef10 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_globals.h @@ -0,0 +1,79 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_GLOBALS_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_GLOBALS_H_ + +#include "ppapi/c/dev/ppb_memory_dev.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_module.h" +#include "ppapi/c/ppb.h" +#include "ppapi/c/ppb_core.h" +#include "ppapi/c/ppb_var.h" +#include "ppapi/c/ppp_input_event.h" +#include "ppapi/c/ppp_instance.h" +#include "ppapi/c/ppp_messaging.h" +#include "native_client/src/untrusted/irt/irt_ppapi.h" + +struct NaClSrpcChannel; + +namespace ppapi_proxy { + +// The main SRPC channel is that used to handle foreground (main thread) +// RPC traffic. +NaClSrpcChannel* GetMainSrpcChannel(); +void SetMainSrpcChannel(NaClSrpcChannel* channel); + +// The upcall SRPC channel is that used to handle other threads' RPC traffic. +NaClSrpcChannel* GetUpcallSrpcChannel(); +void SetUpcallSrpcChannel(NaClSrpcChannel* channel); + +// Save the plugin's module_id, which is used for storage allocation tracking. +void SetModuleIdForSrpcChannel(NaClSrpcChannel* channel, PP_Module module_id); +// Forget the plugin's module_id. +void UnsetModuleIdForSrpcChannel(NaClSrpcChannel* channel); +// Save the plugin's module_id. +PP_Module LookupModuleIdForSrpcChannel(NaClSrpcChannel* channel); + +// Support for getting PPB_ browser interfaces. +// Safe version CHECK's for NULL. +const void* GetBrowserInterface(const char* interface_name); +const void* GetBrowserInterfaceSafe(const char* interface_name); +// Functions marked "shared" are to be provided by both the browser and the +// plugin side of the proxy, so they can be used by the shared proxy code +// under both trusted and untrusted compilation. +const PPB_Core* PPBCoreInterface(); // shared +const PPB_Memory_Dev* PPBMemoryInterface(); // shared +const PPB_Var* PPBVarInterface(); // shared + +// Support for getting PPP_ plugin interfaces. +// Safe version CHECK's for NULL. +// Since no PppRpcServer function will be called if the interface is NULL, +// safe version is used to define interface getters below. +const void* GetPluginInterface(const char* interface_name); +const void* GetPluginInterfaceSafe(const char* interface_name); +const PPP_Find_Dev* PPPFindInterface(); +const PPP_InputEvent* PPPInputEventInterface(); +const PPP_Instance* PPPInstanceInterface(); +const PPP_Messaging* PPPMessagingInterface(); +const PPP_Printing_Dev* PPPPrintingInterface(); +const PPP_Scrollbar_Dev* PPPScrollbarInterface(); +const PPP_Selection_Dev* PPPSelectionInterface(); +const PPP_Widget_Dev* PPPWidgetInterface(); +const PPP_Zoom_Dev* PPPZoomInterface(); + +// Get thread creation/join functions. +const struct PP_ThreadFunctions* GetThreadCreator(); + +// PPAPI constants used in the proxy. +extern const PP_Resource kInvalidResourceId; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_GLOBALS_H_ diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_instance_data.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_instance_data.cc new file mode 100644 index 0000000..bfdfe2b --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_instance_data.cc @@ -0,0 +1,55 @@ +/* + * Copyright 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/plugin_instance_data.h" + +#include <tr1/unordered_map> + +namespace ppapi_proxy { + +namespace { + +typedef std::tr1::unordered_map<PP_Instance, PluginInstanceData*> InstanceMap; + +InstanceMap& GetInstanceMap() { + static InstanceMap map; + return map; +} + +} // namespace + +// static +PluginInstanceData* PluginInstanceData::FromPP(PP_Instance id) { + InstanceMap& map = GetInstanceMap(); + InstanceMap::iterator i = map.find(id); + + return map.end() == i ? NULL : i->second; +} + +// static +void PluginInstanceData::DidCreate(PP_Instance id) { + InstanceMap& map = GetInstanceMap(); + // TODO(neb): figure out how to use CHECK in NaCl land. +// CHECK(map.end() == map.find(id)); + map[id] = new PluginInstanceData(id); +} + +// static +void PluginInstanceData::DidDestroy(PP_Instance id) { + GetInstanceMap().erase(id); +} + +// static +void PluginInstanceData::DidChangeView(PP_Instance id, + PP_Rect position, + PP_Rect clip) { + PluginInstanceData* instance = FromPP(id); + if (instance) { + instance->set_position(position); + } +} + +} // namespace ppapi_proxy diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_instance_data.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_instance_data.h new file mode 100644 index 0000000..475bfd2 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_instance_data.h @@ -0,0 +1,42 @@ +/* + * Copyright 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. + */ + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_INSTANCE_DATA_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_INSTANCE_DATA_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_rect.h" + +namespace ppapi_proxy { + +// Per-instance data on the plugin side. +class PluginInstanceData { + public: + static PluginInstanceData* FromPP(PP_Instance id); + static void DidCreate(PP_Instance id); + static void DidDestroy(PP_Instance id); + static void DidChangeView(PP_Instance id, PP_Rect position, PP_Rect clip); + + PluginInstanceData(PP_Instance id) + : id_(id), position_(PP_MakeRectFromXYWH(0, 0, 0, 0)) { + } + ~PluginInstanceData() {} + + PP_Instance id() { return id_; } + PP_Rect position() { return position_; } + void set_position(PP_Rect position) { position_ = position; } + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(PluginInstanceData); + + PP_Instance id_; + PP_Rect position_; +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_INSTANCE_DATA_H_ diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_main.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_main.cc new file mode 100644 index 0000000..92415bf --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_main.cc @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2010 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/ppruntime.h" + +// PPAPI plugins are actually "hosted" by ppruntime. This is because the +// library needs to start an SRPC loop to dispatch to the stubs. +// +// This definition is weak to allow customers to override it when +// initialization is needed before the main PPAPI processing happens. + +int __attribute__ ((weak)) main(int argc, char* argv[]) { + return PpapiPluginMain(); +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_nacl_file.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_nacl_file.cc new file mode 100644 index 0000000..17573c1 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_nacl_file.cc @@ -0,0 +1,53 @@ +/* + 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/include/nacl_macros.h" +#include "native_client/src/shared/ppapi_proxy/plugin_callback.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/plugin_nacl_file.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "ppapi/c/pp_errors.h" +#include "srpcgen/ppb_rpc.h" + +namespace ppapi_proxy { + +int32_t StreamAsFile(PP_Instance instance, + const char* url, + struct PP_CompletionCallback callback) { + DebugPrintf("NaClFile::StreamAsFile: instance=%"NACL_PRIu32" url=%s\n", + instance, url); + + int32_t callback_id = + CompletionCallbackTable::Get()->AddCallback(callback); + if (callback_id == 0) + return PP_ERROR_BADARGUMENT; + + NaClSrpcError srpc_result = NaClFileRpcClient::StreamAsFile( + GetMainSrpcChannel(), instance, const_cast<char*>(url), callback_id); + DebugPrintf("NaClFile::StreamAsFile: %s\n", NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK) + return PP_OK_COMPLETIONPENDING; + return MayForceCallback(callback, PP_ERROR_FAILED); +} + + +int GetFileDesc(PP_Instance instance, const char* url) { + DebugPrintf("NaClFile::GetFileDesc: instance=%"NACL_PRIu32" url=%s\n", + instance, url); + + int file_desc; + NaClSrpcError srpc_result = NaClFileRpcClient::GetFileDesc( + GetMainSrpcChannel(), instance, const_cast<char*>(url), &file_desc); + DebugPrintf("NaClFile::GetFileDesc: %s\n", NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK) + return file_desc; + return NACL_NO_FILE_DESC; +} + +} // namespace ppapi_proxy diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_nacl_file.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_nacl_file.h new file mode 100644 index 0000000..1129a4b --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_nacl_file.h @@ -0,0 +1,29 @@ +/* + 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. +*/ + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_NACL_FILE_H +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_NACL_FILE_H + +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_instance.h" + +namespace ppapi_proxy { + +// Loads |url| asynchronously notifying the |callback| of the final result. +// If the call cannot be completed asynchronously, |callback| +// will not be invoked. Returns one of the PP_ERROR codes. +int32_t StreamAsFile(PP_Instance instance, + const char* url, + struct PP_CompletionCallback callback); + +// Returns an open file descriptor for a |url| loaded using StreamAsFile() +// or -1 if it has not been loaded. +int GetFileDesc(PP_Instance instance, + const char* url); + +} // namespace ppapi_proxy + +#endif /* NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_NACL_FILE_H */ diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_opengles.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_opengles.cc new file mode 100644 index 0000000..266981c --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_opengles.cc @@ -0,0 +1,781 @@ +// Copyright (c) 2011 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. + +// This file is auto-generated from +// gpu/command_buffer/build_gles2_cmd_buffer.py +// DO NOT EDIT! + +#include "native_client/src/shared/ppapi_proxy/plugin_ppb_graphics_3d.h" + +#include "gpu/command_buffer/client/gles2_implementation.h" +#include "ppapi/c/dev/ppb_opengles_dev.h" + +using ppapi_proxy::PluginGraphics3D; +using ppapi_proxy::PluginResource; + +namespace { + +void ActiveTexture(PP_Resource context, GLenum texture) { + PluginGraphics3D::implFromResource(context)->ActiveTexture(texture); +} +void AttachShader(PP_Resource context, GLuint program, GLuint shader) { + PluginGraphics3D::implFromResource(context)->AttachShader(program, shader); +} +void BindAttribLocation( + PP_Resource context, GLuint program, GLuint index, const char* name) { + PluginGraphics3D::implFromResource( + context)->BindAttribLocation(program, index, name); +} +void BindBuffer(PP_Resource context, GLenum target, GLuint buffer) { + PluginGraphics3D::implFromResource(context)->BindBuffer(target, buffer); +} +void BindFramebuffer(PP_Resource context, GLenum target, GLuint framebuffer) { + PluginGraphics3D::implFromResource( + context)->BindFramebuffer(target, framebuffer); +} +void BindRenderbuffer( + PP_Resource context, GLenum target, GLuint renderbuffer) { + PluginGraphics3D::implFromResource( + context)->BindRenderbuffer(target, renderbuffer); +} +void BindTexture(PP_Resource context, GLenum target, GLuint texture) { + PluginGraphics3D::implFromResource(context)->BindTexture(target, texture); +} +void BlendColor( + PP_Resource context, GLclampf red, GLclampf green, GLclampf blue, + GLclampf alpha) { + PluginGraphics3D::implFromResource( + context)->BlendColor(red, green, blue, alpha); +} +void BlendEquation(PP_Resource context, GLenum mode) { + PluginGraphics3D::implFromResource(context)->BlendEquation(mode); +} +void BlendEquationSeparate( + PP_Resource context, GLenum modeRGB, GLenum modeAlpha) { + PluginGraphics3D::implFromResource( + context)->BlendEquationSeparate(modeRGB, modeAlpha); +} +void BlendFunc(PP_Resource context, GLenum sfactor, GLenum dfactor) { + PluginGraphics3D::implFromResource(context)->BlendFunc(sfactor, dfactor); +} +void BlendFuncSeparate( + PP_Resource context, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, + GLenum dstAlpha) { + PluginGraphics3D::implFromResource( + context)->BlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); +} +void BufferData( + PP_Resource context, GLenum target, GLsizeiptr size, const void* data, + GLenum usage) { + PluginGraphics3D::implFromResource( + context)->BufferData(target, size, data, usage); +} +void BufferSubData( + PP_Resource context, GLenum target, GLintptr offset, GLsizeiptr size, + const void* data) { + PluginGraphics3D::implFromResource( + context)->BufferSubData(target, offset, size, data); +} +GLenum CheckFramebufferStatus(PP_Resource context, GLenum target) { + return PluginGraphics3D::implFromResource( + context)->CheckFramebufferStatus(target); +} +void Clear(PP_Resource context, GLbitfield mask) { + PluginGraphics3D::implFromResource(context)->Clear(mask); +} +void ClearColor( + PP_Resource context, GLclampf red, GLclampf green, GLclampf blue, + GLclampf alpha) { + PluginGraphics3D::implFromResource( + context)->ClearColor(red, green, blue, alpha); +} +void ClearDepthf(PP_Resource context, GLclampf depth) { + PluginGraphics3D::implFromResource(context)->ClearDepthf(depth); +} +void ClearStencil(PP_Resource context, GLint s) { + PluginGraphics3D::implFromResource(context)->ClearStencil(s); +} +void ColorMask( + PP_Resource context, GLboolean red, GLboolean green, GLboolean blue, + GLboolean alpha) { + PluginGraphics3D::implFromResource( + context)->ColorMask(red, green, blue, alpha); +} +void CompileShader(PP_Resource context, GLuint shader) { + PluginGraphics3D::implFromResource(context)->CompileShader(shader); +} +void CompressedTexImage2D( + PP_Resource context, GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLint border, GLsizei imageSize, + const void* data) { + PluginGraphics3D::implFromResource( + context)->CompressedTexImage2D( + target, level, internalformat, width, height, border, imageSize, + data); +} +void CompressedTexSubImage2D( + PP_Resource context, GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLsizei width, GLsizei height, GLenum format, + GLsizei imageSize, const void* data) { + PluginGraphics3D::implFromResource( + context)->CompressedTexSubImage2D( + target, level, xoffset, yoffset, width, height, format, imageSize, + data); +} +void CopyTexImage2D( + PP_Resource context, GLenum target, GLint level, GLenum internalformat, + GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { + PluginGraphics3D::implFromResource( + context)->CopyTexImage2D( + target, level, internalformat, x, y, width, height, border); +} +void CopyTexSubImage2D( + PP_Resource context, GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { + PluginGraphics3D::implFromResource( + context)->CopyTexSubImage2D( + target, level, xoffset, yoffset, x, y, width, height); +} +GLuint CreateProgram(PP_Resource context) { + return PluginGraphics3D::implFromResource(context)->CreateProgram(); +} +GLuint CreateShader(PP_Resource context, GLenum type) { + return PluginGraphics3D::implFromResource(context)->CreateShader(type); +} +void CullFace(PP_Resource context, GLenum mode) { + PluginGraphics3D::implFromResource(context)->CullFace(mode); +} +void DeleteBuffers(PP_Resource context, GLsizei n, const GLuint* buffers) { + PluginGraphics3D::implFromResource(context)->DeleteBuffers(n, buffers); +} +void DeleteFramebuffers( + PP_Resource context, GLsizei n, const GLuint* framebuffers) { + PluginGraphics3D::implFromResource( + context)->DeleteFramebuffers(n, framebuffers); +} +void DeleteProgram(PP_Resource context, GLuint program) { + PluginGraphics3D::implFromResource(context)->DeleteProgram(program); +} +void DeleteRenderbuffers( + PP_Resource context, GLsizei n, const GLuint* renderbuffers) { + PluginGraphics3D::implFromResource( + context)->DeleteRenderbuffers(n, renderbuffers); +} +void DeleteShader(PP_Resource context, GLuint shader) { + PluginGraphics3D::implFromResource(context)->DeleteShader(shader); +} +void DeleteTextures(PP_Resource context, GLsizei n, const GLuint* textures) { + PluginGraphics3D::implFromResource(context)->DeleteTextures(n, textures); +} +void DepthFunc(PP_Resource context, GLenum func) { + PluginGraphics3D::implFromResource(context)->DepthFunc(func); +} +void DepthMask(PP_Resource context, GLboolean flag) { + PluginGraphics3D::implFromResource(context)->DepthMask(flag); +} +void DepthRangef(PP_Resource context, GLclampf zNear, GLclampf zFar) { + PluginGraphics3D::implFromResource(context)->DepthRangef(zNear, zFar); +} +void DetachShader(PP_Resource context, GLuint program, GLuint shader) { + PluginGraphics3D::implFromResource(context)->DetachShader(program, shader); +} +void Disable(PP_Resource context, GLenum cap) { + PluginGraphics3D::implFromResource(context)->Disable(cap); +} +void DisableVertexAttribArray(PP_Resource context, GLuint index) { + PluginGraphics3D::implFromResource(context)->DisableVertexAttribArray(index); +} +void DrawArrays(PP_Resource context, GLenum mode, GLint first, GLsizei count) { + PluginGraphics3D::implFromResource(context)->DrawArrays(mode, first, count); +} +void DrawElements( + PP_Resource context, GLenum mode, GLsizei count, GLenum type, + const void* indices) { + PluginGraphics3D::implFromResource( + context)->DrawElements(mode, count, type, indices); +} +void Enable(PP_Resource context, GLenum cap) { + PluginGraphics3D::implFromResource(context)->Enable(cap); +} +void EnableVertexAttribArray(PP_Resource context, GLuint index) { + PluginGraphics3D::implFromResource(context)->EnableVertexAttribArray(index); +} +void Finish(PP_Resource context) { + PluginGraphics3D::implFromResource(context)->Finish(); +} +void Flush(PP_Resource context) { + PluginGraphics3D::implFromResource(context)->Flush(); +} +void FramebufferRenderbuffer( + PP_Resource context, GLenum target, GLenum attachment, + GLenum renderbuffertarget, GLuint renderbuffer) { + PluginGraphics3D::implFromResource( + context)->FramebufferRenderbuffer( + target, attachment, renderbuffertarget, renderbuffer); +} +void FramebufferTexture2D( + PP_Resource context, GLenum target, GLenum attachment, GLenum textarget, + GLuint texture, GLint level) { + PluginGraphics3D::implFromResource( + context)->FramebufferTexture2D( + target, attachment, textarget, texture, level); +} +void FrontFace(PP_Resource context, GLenum mode) { + PluginGraphics3D::implFromResource(context)->FrontFace(mode); +} +void GenBuffers(PP_Resource context, GLsizei n, GLuint* buffers) { + PluginGraphics3D::implFromResource(context)->GenBuffers(n, buffers); +} +void GenerateMipmap(PP_Resource context, GLenum target) { + PluginGraphics3D::implFromResource(context)->GenerateMipmap(target); +} +void GenFramebuffers(PP_Resource context, GLsizei n, GLuint* framebuffers) { + PluginGraphics3D::implFromResource( + context)->GenFramebuffers(n, framebuffers); +} +void GenRenderbuffers(PP_Resource context, GLsizei n, GLuint* renderbuffers) { + PluginGraphics3D::implFromResource( + context)->GenRenderbuffers(n, renderbuffers); +} +void GenTextures(PP_Resource context, GLsizei n, GLuint* textures) { + PluginGraphics3D::implFromResource(context)->GenTextures(n, textures); +} +void GetActiveAttrib( + PP_Resource context, GLuint program, GLuint index, GLsizei bufsize, + GLsizei* length, GLint* size, GLenum* type, char* name) { + PluginGraphics3D::implFromResource( + context)->GetActiveAttrib( + program, index, bufsize, length, size, type, name); +} +void GetActiveUniform( + PP_Resource context, GLuint program, GLuint index, GLsizei bufsize, + GLsizei* length, GLint* size, GLenum* type, char* name) { + PluginGraphics3D::implFromResource( + context)->GetActiveUniform( + program, index, bufsize, length, size, type, name); +} +void GetAttachedShaders( + PP_Resource context, GLuint program, GLsizei maxcount, GLsizei* count, + GLuint* shaders) { + PluginGraphics3D::implFromResource( + context)->GetAttachedShaders(program, maxcount, count, shaders); +} +GLint GetAttribLocation( + PP_Resource context, GLuint program, const char* name) { + return PluginGraphics3D::implFromResource( + context)->GetAttribLocation(program, name); +} +void GetBooleanv(PP_Resource context, GLenum pname, GLboolean* params) { + PluginGraphics3D::implFromResource(context)->GetBooleanv(pname, params); +} +void GetBufferParameteriv( + PP_Resource context, GLenum target, GLenum pname, GLint* params) { + PluginGraphics3D::implFromResource( + context)->GetBufferParameteriv(target, pname, params); +} +GLenum GetError(PP_Resource context) { + return PluginGraphics3D::implFromResource(context)->GetError(); +} +void GetFloatv(PP_Resource context, GLenum pname, GLfloat* params) { + PluginGraphics3D::implFromResource(context)->GetFloatv(pname, params); +} +void GetFramebufferAttachmentParameteriv( + PP_Resource context, GLenum target, GLenum attachment, GLenum pname, + GLint* params) { + PluginGraphics3D::implFromResource( + context)->GetFramebufferAttachmentParameteriv( + target, attachment, pname, params); +} +void GetIntegerv(PP_Resource context, GLenum pname, GLint* params) { + PluginGraphics3D::implFromResource(context)->GetIntegerv(pname, params); +} +void GetProgramiv( + PP_Resource context, GLuint program, GLenum pname, GLint* params) { + PluginGraphics3D::implFromResource( + context)->GetProgramiv(program, pname, params); +} +void GetProgramInfoLog( + PP_Resource context, GLuint program, GLsizei bufsize, GLsizei* length, + char* infolog) { + PluginGraphics3D::implFromResource( + context)->GetProgramInfoLog(program, bufsize, length, infolog); +} +void GetRenderbufferParameteriv( + PP_Resource context, GLenum target, GLenum pname, GLint* params) { + PluginGraphics3D::implFromResource( + context)->GetRenderbufferParameteriv(target, pname, params); +} +void GetShaderiv( + PP_Resource context, GLuint shader, GLenum pname, GLint* params) { + PluginGraphics3D::implFromResource( + context)->GetShaderiv(shader, pname, params); +} +void GetShaderInfoLog( + PP_Resource context, GLuint shader, GLsizei bufsize, GLsizei* length, + char* infolog) { + PluginGraphics3D::implFromResource( + context)->GetShaderInfoLog(shader, bufsize, length, infolog); +} +void GetShaderPrecisionFormat( + PP_Resource context, GLenum shadertype, GLenum precisiontype, GLint* range, + GLint* precision) { + PluginGraphics3D::implFromResource( + context)->GetShaderPrecisionFormat( + shadertype, precisiontype, range, precision); +} +void GetShaderSource( + PP_Resource context, GLuint shader, GLsizei bufsize, GLsizei* length, + char* source) { + PluginGraphics3D::implFromResource( + context)->GetShaderSource(shader, bufsize, length, source); +} +const GLubyte* GetString(PP_Resource context, GLenum name) { + return PluginGraphics3D::implFromResource(context)->GetString(name); +} +void GetTexParameterfv( + PP_Resource context, GLenum target, GLenum pname, GLfloat* params) { + PluginGraphics3D::implFromResource( + context)->GetTexParameterfv(target, pname, params); +} +void GetTexParameteriv( + PP_Resource context, GLenum target, GLenum pname, GLint* params) { + PluginGraphics3D::implFromResource( + context)->GetTexParameteriv(target, pname, params); +} +void GetUniformfv( + PP_Resource context, GLuint program, GLint location, GLfloat* params) { + PluginGraphics3D::implFromResource( + context)->GetUniformfv(program, location, params); +} +void GetUniformiv( + PP_Resource context, GLuint program, GLint location, GLint* params) { + PluginGraphics3D::implFromResource( + context)->GetUniformiv(program, location, params); +} +GLint GetUniformLocation( + PP_Resource context, GLuint program, const char* name) { + return PluginGraphics3D::implFromResource( + context)->GetUniformLocation(program, name); +} +void GetVertexAttribfv( + PP_Resource context, GLuint index, GLenum pname, GLfloat* params) { + PluginGraphics3D::implFromResource( + context)->GetVertexAttribfv(index, pname, params); +} +void GetVertexAttribiv( + PP_Resource context, GLuint index, GLenum pname, GLint* params) { + PluginGraphics3D::implFromResource( + context)->GetVertexAttribiv(index, pname, params); +} +void GetVertexAttribPointerv( + PP_Resource context, GLuint index, GLenum pname, void** pointer) { + PluginGraphics3D::implFromResource( + context)->GetVertexAttribPointerv(index, pname, pointer); +} +void Hint(PP_Resource context, GLenum target, GLenum mode) { + PluginGraphics3D::implFromResource(context)->Hint(target, mode); +} +GLboolean IsBuffer(PP_Resource context, GLuint buffer) { + return PluginGraphics3D::implFromResource(context)->IsBuffer(buffer); +} +GLboolean IsEnabled(PP_Resource context, GLenum cap) { + return PluginGraphics3D::implFromResource(context)->IsEnabled(cap); +} +GLboolean IsFramebuffer(PP_Resource context, GLuint framebuffer) { + return PluginGraphics3D::implFromResource( + context)->IsFramebuffer(framebuffer); +} +GLboolean IsProgram(PP_Resource context, GLuint program) { + return PluginGraphics3D::implFromResource(context)->IsProgram(program); +} +GLboolean IsRenderbuffer(PP_Resource context, GLuint renderbuffer) { + return PluginGraphics3D::implFromResource( + context)->IsRenderbuffer(renderbuffer); +} +GLboolean IsShader(PP_Resource context, GLuint shader) { + return PluginGraphics3D::implFromResource(context)->IsShader(shader); +} +GLboolean IsTexture(PP_Resource context, GLuint texture) { + return PluginGraphics3D::implFromResource(context)->IsTexture(texture); +} +void LineWidth(PP_Resource context, GLfloat width) { + PluginGraphics3D::implFromResource(context)->LineWidth(width); +} +void LinkProgram(PP_Resource context, GLuint program) { + PluginGraphics3D::implFromResource(context)->LinkProgram(program); +} +void PixelStorei(PP_Resource context, GLenum pname, GLint param) { + PluginGraphics3D::implFromResource(context)->PixelStorei(pname, param); +} +void PolygonOffset(PP_Resource context, GLfloat factor, GLfloat units) { + PluginGraphics3D::implFromResource(context)->PolygonOffset(factor, units); +} +void ReadPixels( + PP_Resource context, GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, void* pixels) { + PluginGraphics3D::implFromResource( + context)->ReadPixels(x, y, width, height, format, type, pixels); +} +void ReleaseShaderCompiler(PP_Resource context) { + PluginGraphics3D::implFromResource(context)->ReleaseShaderCompiler(); +} +void RenderbufferStorage( + PP_Resource context, GLenum target, GLenum internalformat, GLsizei width, + GLsizei height) { + PluginGraphics3D::implFromResource( + context)->RenderbufferStorage(target, internalformat, width, height); +} +void SampleCoverage(PP_Resource context, GLclampf value, GLboolean invert) { + PluginGraphics3D::implFromResource(context)->SampleCoverage(value, invert); +} +void Scissor( + PP_Resource context, GLint x, GLint y, GLsizei width, GLsizei height) { + PluginGraphics3D::implFromResource(context)->Scissor(x, y, width, height); +} +void ShaderBinary( + PP_Resource context, GLsizei n, const GLuint* shaders, GLenum binaryformat, + const void* binary, GLsizei length) { + PluginGraphics3D::implFromResource( + context)->ShaderBinary(n, shaders, binaryformat, binary, length); +} +void ShaderSource( + PP_Resource context, GLuint shader, GLsizei count, const char** str, + const GLint* length) { + PluginGraphics3D::implFromResource( + context)->ShaderSource(shader, count, str, length); +} +void StencilFunc(PP_Resource context, GLenum func, GLint ref, GLuint mask) { + PluginGraphics3D::implFromResource(context)->StencilFunc(func, ref, mask); +} +void StencilFuncSeparate( + PP_Resource context, GLenum face, GLenum func, GLint ref, GLuint mask) { + PluginGraphics3D::implFromResource( + context)->StencilFuncSeparate(face, func, ref, mask); +} +void StencilMask(PP_Resource context, GLuint mask) { + PluginGraphics3D::implFromResource(context)->StencilMask(mask); +} +void StencilMaskSeparate(PP_Resource context, GLenum face, GLuint mask) { + PluginGraphics3D::implFromResource(context)->StencilMaskSeparate(face, mask); +} +void StencilOp(PP_Resource context, GLenum fail, GLenum zfail, GLenum zpass) { + PluginGraphics3D::implFromResource(context)->StencilOp(fail, zfail, zpass); +} +void StencilOpSeparate( + PP_Resource context, GLenum face, GLenum fail, GLenum zfail, + GLenum zpass) { + PluginGraphics3D::implFromResource( + context)->StencilOpSeparate(face, fail, zfail, zpass); +} +void TexImage2D( + PP_Resource context, GLenum target, GLint level, GLint internalformat, + GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, + const void* pixels) { + PluginGraphics3D::implFromResource( + context)->TexImage2D( + target, level, internalformat, width, height, border, format, type, + pixels); +} +void TexParameterf( + PP_Resource context, GLenum target, GLenum pname, GLfloat param) { + PluginGraphics3D::implFromResource( + context)->TexParameterf(target, pname, param); +} +void TexParameterfv( + PP_Resource context, GLenum target, GLenum pname, const GLfloat* params) { + PluginGraphics3D::implFromResource( + context)->TexParameterfv(target, pname, params); +} +void TexParameteri( + PP_Resource context, GLenum target, GLenum pname, GLint param) { + PluginGraphics3D::implFromResource( + context)->TexParameteri(target, pname, param); +} +void TexParameteriv( + PP_Resource context, GLenum target, GLenum pname, const GLint* params) { + PluginGraphics3D::implFromResource( + context)->TexParameteriv(target, pname, params); +} +void TexSubImage2D( + PP_Resource context, GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, + const void* pixels) { + PluginGraphics3D::implFromResource( + context)->TexSubImage2D( + target, level, xoffset, yoffset, width, height, format, type, + pixels); +} +void Uniform1f(PP_Resource context, GLint location, GLfloat x) { + PluginGraphics3D::implFromResource(context)->Uniform1f(location, x); +} +void Uniform1fv( + PP_Resource context, GLint location, GLsizei count, const GLfloat* v) { + PluginGraphics3D::implFromResource(context)->Uniform1fv(location, count, v); +} +void Uniform1i(PP_Resource context, GLint location, GLint x) { + PluginGraphics3D::implFromResource(context)->Uniform1i(location, x); +} +void Uniform1iv( + PP_Resource context, GLint location, GLsizei count, const GLint* v) { + PluginGraphics3D::implFromResource(context)->Uniform1iv(location, count, v); +} +void Uniform2f(PP_Resource context, GLint location, GLfloat x, GLfloat y) { + PluginGraphics3D::implFromResource(context)->Uniform2f(location, x, y); +} +void Uniform2fv( + PP_Resource context, GLint location, GLsizei count, const GLfloat* v) { + PluginGraphics3D::implFromResource(context)->Uniform2fv(location, count, v); +} +void Uniform2i(PP_Resource context, GLint location, GLint x, GLint y) { + PluginGraphics3D::implFromResource(context)->Uniform2i(location, x, y); +} +void Uniform2iv( + PP_Resource context, GLint location, GLsizei count, const GLint* v) { + PluginGraphics3D::implFromResource(context)->Uniform2iv(location, count, v); +} +void Uniform3f( + PP_Resource context, GLint location, GLfloat x, GLfloat y, GLfloat z) { + PluginGraphics3D::implFromResource(context)->Uniform3f(location, x, y, z); +} +void Uniform3fv( + PP_Resource context, GLint location, GLsizei count, const GLfloat* v) { + PluginGraphics3D::implFromResource(context)->Uniform3fv(location, count, v); +} +void Uniform3i( + PP_Resource context, GLint location, GLint x, GLint y, GLint z) { + PluginGraphics3D::implFromResource(context)->Uniform3i(location, x, y, z); +} +void Uniform3iv( + PP_Resource context, GLint location, GLsizei count, const GLint* v) { + PluginGraphics3D::implFromResource(context)->Uniform3iv(location, count, v); +} +void Uniform4f( + PP_Resource context, GLint location, GLfloat x, GLfloat y, GLfloat z, + GLfloat w) { + PluginGraphics3D::implFromResource(context)->Uniform4f(location, x, y, z, w); +} +void Uniform4fv( + PP_Resource context, GLint location, GLsizei count, const GLfloat* v) { + PluginGraphics3D::implFromResource(context)->Uniform4fv(location, count, v); +} +void Uniform4i( + PP_Resource context, GLint location, GLint x, GLint y, GLint z, GLint w) { + PluginGraphics3D::implFromResource(context)->Uniform4i(location, x, y, z, w); +} +void Uniform4iv( + PP_Resource context, GLint location, GLsizei count, const GLint* v) { + PluginGraphics3D::implFromResource(context)->Uniform4iv(location, count, v); +} +void UniformMatrix2fv( + PP_Resource context, GLint location, GLsizei count, GLboolean transpose, + const GLfloat* value) { + PluginGraphics3D::implFromResource( + context)->UniformMatrix2fv(location, count, transpose, value); +} +void UniformMatrix3fv( + PP_Resource context, GLint location, GLsizei count, GLboolean transpose, + const GLfloat* value) { + PluginGraphics3D::implFromResource( + context)->UniformMatrix3fv(location, count, transpose, value); +} +void UniformMatrix4fv( + PP_Resource context, GLint location, GLsizei count, GLboolean transpose, + const GLfloat* value) { + PluginGraphics3D::implFromResource( + context)->UniformMatrix4fv(location, count, transpose, value); +} +void UseProgram(PP_Resource context, GLuint program) { + PluginGraphics3D::implFromResource(context)->UseProgram(program); +} +void ValidateProgram(PP_Resource context, GLuint program) { + PluginGraphics3D::implFromResource(context)->ValidateProgram(program); +} +void VertexAttrib1f(PP_Resource context, GLuint indx, GLfloat x) { + PluginGraphics3D::implFromResource(context)->VertexAttrib1f(indx, x); +} +void VertexAttrib1fv(PP_Resource context, GLuint indx, const GLfloat* values) { + PluginGraphics3D::implFromResource(context)->VertexAttrib1fv(indx, values); +} +void VertexAttrib2f(PP_Resource context, GLuint indx, GLfloat x, GLfloat y) { + PluginGraphics3D::implFromResource(context)->VertexAttrib2f(indx, x, y); +} +void VertexAttrib2fv(PP_Resource context, GLuint indx, const GLfloat* values) { + PluginGraphics3D::implFromResource(context)->VertexAttrib2fv(indx, values); +} +void VertexAttrib3f( + PP_Resource context, GLuint indx, GLfloat x, GLfloat y, GLfloat z) { + PluginGraphics3D::implFromResource(context)->VertexAttrib3f(indx, x, y, z); +} +void VertexAttrib3fv(PP_Resource context, GLuint indx, const GLfloat* values) { + PluginGraphics3D::implFromResource(context)->VertexAttrib3fv(indx, values); +} +void VertexAttrib4f( + PP_Resource context, GLuint indx, GLfloat x, GLfloat y, GLfloat z, + GLfloat w) { + PluginGraphics3D::implFromResource( + context)->VertexAttrib4f(indx, x, y, z, w); +} +void VertexAttrib4fv(PP_Resource context, GLuint indx, const GLfloat* values) { + PluginGraphics3D::implFromResource(context)->VertexAttrib4fv(indx, values); +} +void VertexAttribPointer( + PP_Resource context, GLuint indx, GLint size, GLenum type, + GLboolean normalized, GLsizei stride, const void* ptr) { + PluginGraphics3D::implFromResource( + context)->VertexAttribPointer(indx, size, type, normalized, stride, ptr); +} +void Viewport( + PP_Resource context, GLint x, GLint y, GLsizei width, GLsizei height) { + PluginGraphics3D::implFromResource(context)->Viewport(x, y, width, height); +} + +} // namespace + +const PPB_OpenGLES2_Dev* PluginGraphics3D::GetOpenGLESInterface() { + const static struct PPB_OpenGLES2_Dev ppb_opengles = { + &ActiveTexture, + &AttachShader, + &BindAttribLocation, + &BindBuffer, + &BindFramebuffer, + &BindRenderbuffer, + &BindTexture, + &BlendColor, + &BlendEquation, + &BlendEquationSeparate, + &BlendFunc, + &BlendFuncSeparate, + &BufferData, + &BufferSubData, + &CheckFramebufferStatus, + &Clear, + &ClearColor, + &ClearDepthf, + &ClearStencil, + &ColorMask, + &CompileShader, + &CompressedTexImage2D, + &CompressedTexSubImage2D, + &CopyTexImage2D, + &CopyTexSubImage2D, + &CreateProgram, + &CreateShader, + &CullFace, + &DeleteBuffers, + &DeleteFramebuffers, + &DeleteProgram, + &DeleteRenderbuffers, + &DeleteShader, + &DeleteTextures, + &DepthFunc, + &DepthMask, + &DepthRangef, + &DetachShader, + &Disable, + &DisableVertexAttribArray, + &DrawArrays, + &DrawElements, + &Enable, + &EnableVertexAttribArray, + &Finish, + &Flush, + &FramebufferRenderbuffer, + &FramebufferTexture2D, + &FrontFace, + &GenBuffers, + &GenerateMipmap, + &GenFramebuffers, + &GenRenderbuffers, + &GenTextures, + &GetActiveAttrib, + &GetActiveUniform, + &GetAttachedShaders, + &GetAttribLocation, + &GetBooleanv, + &GetBufferParameteriv, + &GetError, + &GetFloatv, + &GetFramebufferAttachmentParameteriv, + &GetIntegerv, + &GetProgramiv, + &GetProgramInfoLog, + &GetRenderbufferParameteriv, + &GetShaderiv, + &GetShaderInfoLog, + &GetShaderPrecisionFormat, + &GetShaderSource, + &GetString, + &GetTexParameterfv, + &GetTexParameteriv, + &GetUniformfv, + &GetUniformiv, + &GetUniformLocation, + &GetVertexAttribfv, + &GetVertexAttribiv, + &GetVertexAttribPointerv, + &Hint, + &IsBuffer, + &IsEnabled, + &IsFramebuffer, + &IsProgram, + &IsRenderbuffer, + &IsShader, + &IsTexture, + &LineWidth, + &LinkProgram, + &PixelStorei, + &PolygonOffset, + &ReadPixels, + &ReleaseShaderCompiler, + &RenderbufferStorage, + &SampleCoverage, + &Scissor, + &ShaderBinary, + &ShaderSource, + &StencilFunc, + &StencilFuncSeparate, + &StencilMask, + &StencilMaskSeparate, + &StencilOp, + &StencilOpSeparate, + &TexImage2D, + &TexParameterf, + &TexParameterfv, + &TexParameteri, + &TexParameteriv, + &TexSubImage2D, + &Uniform1f, + &Uniform1fv, + &Uniform1i, + &Uniform1iv, + &Uniform2f, + &Uniform2fv, + &Uniform2i, + &Uniform2iv, + &Uniform3f, + &Uniform3fv, + &Uniform3i, + &Uniform3iv, + &Uniform4f, + &Uniform4fv, + &Uniform4i, + &Uniform4iv, + &UniformMatrix2fv, + &UniformMatrix3fv, + &UniformMatrix4fv, + &UseProgram, + &ValidateProgram, + &VertexAttrib1f, + &VertexAttrib1fv, + &VertexAttrib2f, + &VertexAttrib2fv, + &VertexAttrib3f, + &VertexAttrib3fv, + &VertexAttrib4f, + &VertexAttrib4fv, + &VertexAttribPointer, + &Viewport + }; + return &ppb_opengles; +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb.cc new file mode 100644 index 0000000..cb47725 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb.cc @@ -0,0 +1,129 @@ +// 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. +// +// 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_cursor_control.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_graphics_2d.h" +#include "native_client/src/shared/ppapi_proxy/plugin_ppb_graphics_3d.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_pdf.h" +#include "native_client/src/shared/ppapi_proxy/plugin_ppb_scrollbar.h" +#include "native_client/src/shared/ppapi_proxy/plugin_ppb_testing.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_widget.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_CORE_INTERFACE, PluginCore::GetInterface(), true }, + { PPB_CURSOR_CONTROL_DEV_INTERFACE, PluginCursorControl::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_GRAPHICS_2D_INTERFACE, PluginGraphics2D::GetInterface(), true }, + { PPB_GRAPHICS_3D_DEV_INTERFACE, PluginGraphics3D::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_MEMORY_DEV_INTERFACE, PluginMemory::GetInterface(), true }, + { PPB_MESSAGING_INTERFACE, PluginMessaging::GetInterface(), true }, + { PPB_MOUSE_INPUT_EVENT_INTERFACE, PluginInputEvent::GetMouseInterface(), + true }, + { PPB_OPENGLES2_DEV_INTERFACE, PluginGraphics3D::GetOpenGLESInterface(), + true }, + { PPB_PDF_INTERFACE, PluginPDF::GetInterface(), true }, + { PPB_SCROLLBAR_DEV_INTERFACE, PluginScrollbar::GetInterface(), true }, + { PPB_TESTING_DEV_INTERFACE, PluginTesting::GetInterface(), true }, + { PPB_URLLOADER_INTERFACE, PluginURLLoader::GetInterface(), true }, + { PPB_URLREQUESTINFO_INTERFACE, PluginURLRequestInfo::GetInterface(), true }, + { PPB_URLRESPONSEINFO_INTERFACE, PluginURLResponseInfo::GetInterface(), + true }, + { PPB_VAR_INTERFACE, PluginVar::GetInterface(), true }, + { PPB_WHEEL_INPUT_EVENT_INTERFACE, PluginInputEvent::GetWheelInterface(), + true }, + { PPB_WIDGET_DEV_INTERFACE, PluginWidget::GetInterface(), 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 diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_audio.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_audio.cc new file mode 100644 index 0000000..30f7262 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_audio.cc @@ -0,0 +1,318 @@ +// Copyright (c) 2010 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/plugin_ppb_audio.h" + +#include <pthread.h> +#include <stdio.h> +#include <string.h> +#include <sys/errno.h> +#include <sys/mman.h> +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/plugin_resource.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "native_client/src/untrusted/nacl/syscall_bindings_trampoline.h" +#include "ppapi/c/ppb_audio.h" +#include "ppapi/c/ppb_audio_config.h" +#include "ppapi/cpp/module_impl.h" +#include "srpcgen/ppb_rpc.h" +#include "srpcgen/ppp_rpc.h" + +namespace ppapi_proxy { +namespace { + +// round size up to next 64k +size_t ceil64k(size_t n) { + return (n + 0xFFFF) & (~0xFFFF); +} + +} // namespace + +PluginAudio::PluginAudio() : + resource_(kInvalidResourceId), + socket_(-1), + shm_(-1), + shm_size_(0), + shm_buffer_(NULL), + state_(AUDIO_INCOMPLETE), + thread_id_(), + thread_active_(false), + user_callback_(NULL), + user_data_(NULL) { + DebugPrintf("PluginAudio::PluginAudio\n"); +} + +PluginAudio::~PluginAudio() { + DebugPrintf("PluginAudio::~PluginAudio\n"); + // Ensure audio thread is not active. + if (resource_ != kInvalidResourceId) + GetInterface()->StopPlayback(resource_); + // Unmap the shared memory buffer, if present. + if (shm_buffer_) { + munmap(shm_buffer_, ceil64k(shm_size_)); + shm_buffer_ = NULL; + shm_size_ = 0; + } + // Close the handles. + if (shm_ != -1) { + close(shm_); + shm_ = -1; + } + if (socket_ != -1) { + close(socket_); + socket_ = -1; + } +} + +bool PluginAudio::InitFromBrowserResource(PP_Resource resource) { + DebugPrintf("PluginAudio::InitFromBrowserResource: resource=%"NACL_PRIu32"\n", + resource); + resource_ = resource; + return true; +} + +void PluginAudio::AudioThread(void* self) { + PluginAudio* audio = static_cast<PluginAudio*>(self); + DebugPrintf("PluginAudio::AudioThread: self=%p\n", self); + while (true) { + int32_t sync_value; + // block on socket read + ssize_t r = read(audio->socket_, &sync_value, sizeof(sync_value)); + // StopPlayback() will send a value of -1 over the sync_socket + if ((sizeof(sync_value) != r) || (-1 == sync_value)) + break; + // invoke user callback, get next buffer of audio data + audio->user_callback_(audio->shm_buffer_, + audio->shm_size_, + audio->user_data_); + } +} + +void PluginAudio::StreamCreated(NaClSrpcImcDescType socket, + NaClSrpcImcDescType shm, size_t shm_size) { + DebugPrintf("PluginAudio::StreamCreated: shm=%"NACL_PRIu32"" + " shm_size=%"NACL_PRIuS"\n", shm, shm_size); + socket_ = socket; + shm_ = shm; + shm_size_ = shm_size; + shm_buffer_ = mmap(NULL, + ceil64k(shm_size), + PROT_READ | PROT_WRITE, + MAP_SHARED, + shm, + 0); + if (MAP_FAILED != shm_buffer_) { + if (state() == AUDIO_PENDING) { + StartAudioThread(); + } else { + set_state(AUDIO_READY); + } + } else { + shm_buffer_ = NULL; + } +} + +bool PluginAudio::StartAudioThread() { + // clear contents of shm buffer before spinning up audio thread + DebugPrintf("PluginAudio::StartAudioThread\n"); + memset(shm_buffer_, 0, shm_size_); + const struct PP_ThreadFunctions* thread_funcs = GetThreadCreator(); + if (NULL == thread_funcs->thread_create || + NULL == thread_funcs->thread_join) { + return false; + } + int ret = thread_funcs->thread_create(&thread_id_, AudioThread, this); + if (0 == ret) { + thread_active_ = true; + set_state(AUDIO_PLAYING); + return true; + } + return false; +} + +bool PluginAudio::StopAudioThread() { + DebugPrintf("PluginAudio::StopAudioThread\n"); + if (thread_active_) { + int ret = GetThreadCreator()->thread_join(thread_id_); + if (0 == ret) { + thread_active_ = false; + set_state(AUDIO_READY); + return true; + } + } + return false; +} + +// Start of untrusted PPB_Audio functions +namespace { + +PP_Resource Create(PP_Instance instance, + PP_Resource config, + PPB_Audio_Callback user_callback, + void* user_data) { + DebugPrintf("PPB_Audio::Create: instance=%"NACL_PRIu32" config=%"NACL_PRIu32 + " user_callback=%p user_data=%p\n", + instance, config, user_callback, user_data); + PP_Resource audio_resource; + // Proxy to browser Create, get audio PP_Resource + NaClSrpcError srpc_result = PpbAudioRpcClient::PPB_Audio_Create( + GetMainSrpcChannel(), + instance, + config, + &audio_resource); + DebugPrintf("PPB_Audio::Create: %s\n", NaClSrpcErrorString(srpc_result)); + if (NACL_SRPC_RESULT_OK != srpc_result) { + return kInvalidResourceId; + } + if (kInvalidResourceId == audio_resource) { + return kInvalidResourceId; + } + scoped_refptr<PluginAudio> audio = + PluginResource::AdoptAs<PluginAudio>(audio_resource); + if (audio.get()) { + audio->set_callback(user_callback, user_data); + return audio_resource; + } + return kInvalidResourceId; +} + +PP_Bool IsAudio(PP_Resource resource) { + int32_t success; + DebugPrintf("PPB_Audio::IsAudio: resource=%"NACL_PRIu32"\n", resource); + NaClSrpcError srpc_result = + PpbAudioRpcClient::PPB_Audio_IsAudio( + GetMainSrpcChannel(), + resource, + &success); + DebugPrintf("PPB_Audio::IsAudio: %s\n", NaClSrpcErrorString(srpc_result)); + if (NACL_SRPC_RESULT_OK != srpc_result) { + return PP_FALSE; + } + return PP_FromBool(success); +} + +PP_Resource GetCurrentConfig(PP_Resource audio) { + DebugPrintf("PPB_Audio::GetCurrentConfig: audio=%"NACL_PRIu32"\n", audio); + PP_Resource config_resource; + NaClSrpcError srpc_result = + PpbAudioRpcClient::PPB_Audio_GetCurrentConfig( + GetMainSrpcChannel(), + audio, + &config_resource); + DebugPrintf("PPB_Audio::GetCurrentConfig: %s\n", + NaClSrpcErrorString(srpc_result)); + if (NACL_SRPC_RESULT_OK != srpc_result) { + return kInvalidResourceId; + } + return config_resource; +} + +PP_Bool StartPlayback(PP_Resource audio_resource) { + DebugPrintf("PPB_Audio::StartPlayback: audio_resource=%"NACL_PRIu32"\n", + audio_resource); + scoped_refptr<PluginAudio> audio = + PluginResource::GetAs<PluginAudio>(audio_resource); + if (NULL == audio.get()) { + return PP_FALSE; + } + if (audio->state() == AUDIO_INCOMPLETE) { + audio->set_state(AUDIO_PENDING); + } + if (audio->state() == AUDIO_READY) { + if (!audio->StartAudioThread()) { + return PP_FALSE; + } + } + int32_t success; + NaClSrpcError srpc_result = + PpbAudioRpcClient::PPB_Audio_StartPlayback( + GetMainSrpcChannel(), + audio_resource, + &success); + DebugPrintf("PPB_Audio::StartPlayback: %s\n", + NaClSrpcErrorString(srpc_result)); + if (NACL_SRPC_RESULT_OK != srpc_result || !success) { + return PP_FALSE; + } + return PP_TRUE; +} + +PP_Bool StopPlayback(PP_Resource audio_resource) { + DebugPrintf("PPB_Audio::StopPlayback: audio_resource=%"NACL_PRIu32"\n", + audio_resource); + scoped_refptr<PluginAudio> audio = + PluginResource::GetAs<PluginAudio>(audio_resource); + if (NULL == audio.get()) { + return PP_FALSE; + } + if (audio->state() == AUDIO_PENDING) { + // audio is pending to start, but StreamCreated() hasn't occurred yet... + audio->set_state(AUDIO_INCOMPLETE); + } + // RPC to trusted side + int32_t success; + NaClSrpcError srpc_result = + PpbAudioRpcClient::PPB_Audio_StopPlayback( + GetMainSrpcChannel(), + audio_resource, + &success); + DebugPrintf("PPB_Audio::StopPlayback: %s\n", + NaClSrpcErrorString(srpc_result)); + if (NACL_SRPC_RESULT_OK != srpc_result) { + return PP_FALSE; + } + if (audio->state() != AUDIO_PLAYING) { + return PP_FromBool(success); + } + // stop and join the audio thread + return PP_FromBool(audio->StopAudioThread()); +} +} // namespace + +const PPB_Audio* PluginAudio::GetInterface() { + DebugPrintf("PluginAudio::GetInterface\n"); + static const PPB_Audio audio_interface = { + Create, + IsAudio, + GetCurrentConfig, + StartPlayback, + StopPlayback, + }; + return &audio_interface; +} +} // namespace ppapi_proxy + +using ppapi_proxy::DebugPrintf; + +// PppAudioRpcServer::PPP_Audio_StreamCreated() must be in global +// namespace. This function receives handles for the socket and shared +// memory, provided by the trusted audio implementation. +void PppAudioRpcServer::PPP_Audio_StreamCreated( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource audio_resource, + NaClSrpcImcDescType shm, + int32_t shm_size, + NaClSrpcImcDescType sync_socket) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + DebugPrintf("PPP_Audio::StreamCreated: audio_resource=%"NACL_PRIu32 + " shm=%"NACL_PRIx32" shm_size=%"NACL_PRIuS + " sync_socket=%"NACL_PRIx32"\n", + audio_resource, shm, shm_size, sync_socket); + scoped_refptr<ppapi_proxy::PluginAudio> audio = + ppapi_proxy::PluginResource:: + GetAs<ppapi_proxy::PluginAudio>(audio_resource); + if (NULL == audio.get()) { + // Ignore if no audio_resource -> audio_instance mapping exists, + // the app may have shutdown audio before StreamCreated() invoked. + rpc->result = NACL_SRPC_RESULT_OK; + return; + } + audio->StreamCreated(sync_socket, shm, shm_size); + rpc->result = NACL_SRPC_RESULT_OK; +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_audio.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_audio.h new file mode 100644 index 0000000..c0f94d5 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_audio.h @@ -0,0 +1,65 @@ +// Copyright 2010 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_AUDIO_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_AUDIO_H_ + +#include <nacl/nacl_srpc.h> +#include <pthread.h> +#include "native_client/src/include/nacl_base.h" +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/include/ref_counted.h" +#include "native_client/src/shared/ppapi_proxy/plugin_resource.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/ppb_audio.h" + +namespace ppapi_proxy { + +enum PluginAudioState { + AUDIO_INCOMPLETE = 0, // StreamCreated not yet invoked + AUDIO_PENDING, // Incomplete and app requested StartPlayback + AUDIO_READY, // StreamCreated invoked, ready for playback + AUDIO_PLAYING // Audio in playback +}; + +// Implements the untrusted side of the PPB_Audio interface. +// All methods in PluginAudio class will be invoked on the main thread. +// The only exception is AudioThread(), which will invoke the application +// supplied callback to periodically obtain more audio data. +class PluginAudio : public PluginResource { + public: + PluginAudio(); + virtual ~PluginAudio(); + void StreamCreated(NaClSrpcImcDescType socket, + NaClSrpcImcDescType shm, size_t shm_size); + void set_state(PluginAudioState state) { state_ = state; } + void set_callback(PPB_Audio_Callback user_callback, void* user_data) { + user_callback_ = user_callback; + user_data_ = user_data; + } + PluginAudioState state() { return state_; } + bool StartAudioThread(); + bool StopAudioThread(); + static void AudioThread(void* self); + static const PPB_Audio* GetInterface(); + virtual bool InitFromBrowserResource(PP_Resource resource); + private: + PP_Resource resource_; + NaClSrpcImcDescType socket_; + NaClSrpcImcDescType shm_; + size_t shm_size_; + void *shm_buffer_; + PluginAudioState state_; + uintptr_t thread_id_; + bool thread_active_; + PPB_Audio_Callback user_callback_; + void* user_data_; + IMPLEMENT_RESOURCE(PluginAudio); + NACL_DISALLOW_COPY_AND_ASSIGN(PluginAudio); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_AUDIO_H_ diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_audio_config.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_audio_config.cc new file mode 100644 index 0000000..590da47 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_audio_config.cc @@ -0,0 +1,121 @@ +// Copyright (c) 2010 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/plugin_ppb_audio_config.h" + +#include <stdio.h> +#include <string.h> +#include "srpcgen/ppb_rpc.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "ppapi/c/ppb_audio_config.h" + +namespace ppapi_proxy { + +namespace { + +PP_AudioSampleRate GetSampleRate(PP_Resource config) { + DebugPrintf("PPB_AudioConfig::GetSampleRate: config=%"NACL_PRIu32"\n", + config); + int32_t sample_rate; + NaClSrpcError srpc_result = + PpbAudioConfigRpcClient::PPB_AudioConfig_GetSampleRate( + GetMainSrpcChannel(), + config, + &sample_rate); + DebugPrintf("PPB_AudioConfig::GetSampleRate: %s\n", + NaClSrpcErrorString(srpc_result)); + if (NACL_SRPC_RESULT_OK == srpc_result) { + return static_cast<PP_AudioSampleRate>(sample_rate); + } + return PP_AUDIOSAMPLERATE_NONE; +} + +uint32_t GetSampleFrameCount(PP_Resource config) { + DebugPrintf("PPB_AudioConfig::GetSampleFrameCount: config=%"NACL_PRIu32"\n", + config); + int32_t sample_frame_count; + NaClSrpcError srpc_result = + PpbAudioConfigRpcClient::PPB_AudioConfig_GetSampleFrameCount( + GetMainSrpcChannel(), + config, + &sample_frame_count); + DebugPrintf("PPB_AudioConfig::GetSampleFrameCount: %s\n", + NaClSrpcErrorString(srpc_result)); + if (NACL_SRPC_RESULT_OK == srpc_result) { + return static_cast<uint32_t>(sample_frame_count); + } + return 0; +} + +uint32_t RecommendSampleFrameCount(PP_AudioSampleRate sample_rate, + uint32_t request_sample_frame_count) { + DebugPrintf("PPB_AudioConfig::RecommendSampleFrameCount"); + int32_t out_sample_frame_count; + NaClSrpcError srpc_result = + PpbAudioConfigRpcClient::PPB_AudioConfig_RecommendSampleFrameCount( + GetMainSrpcChannel(), + static_cast<int32_t>(sample_rate), + static_cast<int32_t>(request_sample_frame_count), + &out_sample_frame_count); + DebugPrintf("PPB_AudioConfig::RecommendSampleFrameCount: %s\n", + NaClSrpcErrorString(srpc_result)); + if (NACL_SRPC_RESULT_OK == srpc_result) { + return static_cast<uint32_t>(out_sample_frame_count); + } + return 0; +} + +PP_Bool IsAudioConfig(PP_Resource resource) { + DebugPrintf("PPB_AudioConfig::IsAudioConfig: resource=%"NACL_PRIu32"\n", + resource); + int32_t success; + NaClSrpcError srpc_result = + PpbAudioConfigRpcClient::PPB_AudioConfig_IsAudioConfig( + GetMainSrpcChannel(), + resource, + &success); + DebugPrintf("PPB_AudioConfig::IsAudioConfig: %s\n", + NaClSrpcErrorString(srpc_result)); + if (NACL_SRPC_RESULT_OK == srpc_result && success) { + return PP_TRUE; + } + return PP_FALSE; +} + +PP_Resource CreateStereo16Bit(PP_Instance instance, + PP_AudioSampleRate sample_rate, + uint32_t sample_frame_count) { + DebugPrintf("PPB_AudioConfig::CreateStereo16Bit: instance=%"NACL_PRIu32"\n", + instance); + PP_Resource resource; + NaClSrpcError srpc_result = + PpbAudioConfigRpcClient::PPB_AudioConfig_CreateStereo16Bit( + GetMainSrpcChannel(), + instance, + static_cast<int32_t>(sample_rate), + static_cast<int32_t>(sample_frame_count), + &resource); + DebugPrintf("PPB_AudioConfig::CreateStereo16Bit: %s\n", + NaClSrpcErrorString(srpc_result)); + if (NACL_SRPC_RESULT_OK == srpc_result) { + return resource; + } + return kInvalidResourceId; +} +} // namespace + +const PPB_AudioConfig* PluginAudioConfig::GetInterface() { + static const PPB_AudioConfig audio_config_interface = { + CreateStereo16Bit, + RecommendSampleFrameCount, + IsAudioConfig, + GetSampleRate, + GetSampleFrameCount, + }; + return &audio_config_interface; +} +} // namespace ppapi_proxy diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_audio_config.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_audio_config.h new file mode 100644 index 0000000..567f49d --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_audio_config.h @@ -0,0 +1,25 @@ +// Copyright 2010 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_AUDIO_CONFIG_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_AUDIO_CONFIG_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/shared/ppapi_proxy/plugin_resource.h" +#include "ppapi/c/ppb_audio_config.h" + +namespace ppapi_proxy { + +// Implements the untrusted side of the PPB_AudioConfig interface. +class PluginAudioConfig : public PluginResource { + public: + static const PPB_AudioConfig* GetInterface(); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(PluginAudioConfig); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_AUDIO_CONFIG_H_ diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_buffer.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_buffer.cc new file mode 100644 index 0000000..bb5ec95 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_buffer.cc @@ -0,0 +1,57 @@ +// Copyright 2010 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/plugin_ppb_buffer.h" + +#include <stdio.h> +#include <string.h> +#include "srpcgen/ppb_rpc.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "ppapi/c/dev/ppb_buffer_dev.h" + +namespace ppapi_proxy { + +namespace { +PP_Resource Create(PP_Module module, uint32_t size_in_bytes) { + UNREFERENCED_PARAMETER(module); + UNREFERENCED_PARAMETER(size_in_bytes); + return kInvalidResourceId; +} + +PP_Bool IsBuffer(PP_Resource resource) { + return PluginResource::GetAs<PluginBuffer>(resource).get() + ? PP_TRUE : PP_FALSE; +} + +PP_Bool Describe(PP_Resource resource, uint32_t* size_in_bytes) { + UNREFERENCED_PARAMETER(resource); + UNREFERENCED_PARAMETER(size_in_bytes); + return PP_FALSE; +} + +void* Map(PP_Resource resource) { + UNREFERENCED_PARAMETER(resource); + return NULL; +} + +void Unmap(PP_Resource resource) { + UNREFERENCED_PARAMETER(resource); +} +} // namespace + +const PPB_Buffer_Dev* PluginBuffer::GetInterface() { + static const PPB_Buffer_Dev buffer_interface = { + Create, + IsBuffer, + Describe, + Map, + Unmap, + }; + return &buffer_interface; +} + +} // namespace ppapi_proxy diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_buffer.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_buffer.h new file mode 100644 index 0000000..6a044e6 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_buffer.h @@ -0,0 +1,26 @@ +// Copyright 2010 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_BUFFER_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_BUFFER_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/shared/ppapi_proxy/plugin_resource.h" +#include "ppapi/c/dev/ppb_buffer_dev.h" + +namespace ppapi_proxy { + +// Implements the untrusted side of the PPB_Buffer interface. +class PluginBuffer : public PluginResource { + public: + static const PPB_Buffer_Dev* GetInterface(); + + private: + IMPLEMENT_RESOURCE(PluginBuffer); + NACL_DISALLOW_COPY_AND_ASSIGN(PluginBuffer); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_BUFFER_H_ diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_core.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_core.cc new file mode 100644 index 0000000..df44466 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_core.cc @@ -0,0 +1,146 @@ +// Copyright 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/plugin_ppb_core.h" +#include <stdio.h> +#include <map> +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/plugin_callback.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/plugin_resource_tracker.h" +#include "native_client/src/shared/ppapi_proxy/plugin_upcall.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/ppb_core.h" +#include "srpcgen/ppb_rpc.h" + +using ppapi_proxy::DebugPrintf; +using ppapi_proxy::GetMainSrpcChannel; + +// All of the methods here are invoked from the plugin's main (UI) thread, +// so no locking is done. + +namespace { + +__thread bool is_main_thread = false; +bool main_thread_marked = false; + +// Increment the reference count for a specified resource. This only takes +// care of the plugin's reference count - the Resource should obtain the +// browser reference when it stores the browser's Resource id. When the +// Resource's reference count goes to zero, the destructor should make sure +// the browser reference is returned. +void AddRefResource(PP_Resource resource) { + DebugPrintf("PPB_Core::AddRefResource: resource=%"NACL_PRIu32"\n", + resource); + if (!ppapi_proxy::PluginResourceTracker::Get()->AddRefResource(resource)) { + DebugPrintf("PPB_Core::AddRefResource: not tracked locally\n"); + NaClSrpcError srpc_result = PpbCoreRpcClient::PPB_Core_AddRefResource( + GetMainSrpcChannel(), resource); + DebugPrintf("PPB_Core::AddRefResource: %s\n", + NaClSrpcErrorString(srpc_result)); + + } +} + +void ReleaseResource(PP_Resource resource) { + DebugPrintf("PPB_Core::ReleaseResource: resource=%"NACL_PRIu32"\n", + resource); + if (!ppapi_proxy::PluginResourceTracker::Get()->UnrefResource(resource)) { + DebugPrintf("PPB_Core::ReleaseResource: not tracked locally\n"); + NaClSrpcError srpc_result = PpbCoreRpcClient::PPB_Core_ReleaseResource( + GetMainSrpcChannel(), resource); + DebugPrintf("PPB_Core::ReleaseResource: %s\n", + NaClSrpcErrorString(srpc_result)); + } +} + +PP_TimeTicks GetTime() { + DebugPrintf("PPB_Core::GetTime\n"); + double time; + NaClSrpcError srpc_result = PpbCoreRpcClient::PPB_Core_GetTime( + GetMainSrpcChannel(), &time); + DebugPrintf("PPB_Core::GetTime: %s\n", NaClSrpcErrorString(srpc_result)); + if (srpc_result != NACL_SRPC_RESULT_OK) { + return static_cast<PP_Time>(-1.0); + } else { + return static_cast<PP_Time>(time); + } +} + +PP_TimeTicks GetTimeTicks() { + DebugPrintf("PPB_Core::GetTimeTicks\n"); + double time_ticks; + NaClSrpcError srpc_result = PpbCoreRpcClient::PPB_Core_GetTimeTicks( + GetMainSrpcChannel(), &time_ticks); + DebugPrintf("PPB_Core::GetTimeTicks: %s\n", NaClSrpcErrorString(srpc_result)); + if (srpc_result != NACL_SRPC_RESULT_OK) { + return static_cast<PP_TimeTicks>(-1.0); + } else { + return static_cast<PP_TimeTicks>(time_ticks); + } +} + +PP_Bool IsMainThread() { + DebugPrintf("PPB_Core::IsMainThread\n"); + return PP_FromBool(is_main_thread); +} + +void CallOnMainThread(int32_t delay_in_milliseconds, + PP_CompletionCallback callback, + int32_t result) { + if (!IsMainThread()) { + ppapi_proxy::PluginUpcallCoreCallOnMainThread( + delay_in_milliseconds, callback, result); + return; + } + + int32_t callback_id = + ppapi_proxy::CompletionCallbackTable::Get()->AddCallback(callback); + if (callback_id == 0) + return; + + NaClSrpcError srpc_result = + PpbCoreRpcClient::PPB_Core_CallOnMainThread( + ppapi_proxy::GetMainSrpcChannel(), + delay_in_milliseconds, + callback_id, + result); + DebugPrintf("PPB_Core::CallOnMainThread: %s\n", + NaClSrpcErrorString(srpc_result)); +} + +} // namespace + +namespace ppapi_proxy { + +const PPB_Core* PluginCore::GetInterface() { + static const PPB_Core core_interface = { + AddRefResource, + ReleaseResource, + GetTime, + GetTimeTicks, + CallOnMainThread, + IsMainThread + }; + return &core_interface; +} + +void PluginCore::MarkMainThread() { + if (main_thread_marked) { + // A main thread was already designated. Fail. + NACL_NOTREACHED(); + } else { + is_main_thread = true; + // Setting this once works because the main thread will call this function + // before calling any pthread_creates. Hence the result is already + // published before other threads might attempt to call it. + main_thread_marked = true; + } +} + + +} // namespace ppapi_proxy diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_core.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_core.h new file mode 100644 index 0000000..4621465 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_core.h @@ -0,0 +1,30 @@ +// Copyright 2010 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_CORE_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_CORE_H_ + +#include "native_client/src/include/nacl_macros.h" + +class PPB_Core; + +namespace ppapi_proxy { + +// Implements the untrusted side of the PPB_Core interface. +// We will also need an rpc service to implement the trusted side, which is a +// very thin wrapper around the PPB_Core interface returned from the browser. +class PluginCore { + public: + // Return an interface pointer usable by PPAPI plugins. + static const PPB_Core* GetInterface(); + // Mark the calling thread as the main thread for IsMainThread. + static void MarkMainThread(); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(PluginCore); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_CORE_H_ diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_cursor_control.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_cursor_control.cc new file mode 100644 index 0000000..c7defd6 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_cursor_control.cc @@ -0,0 +1,140 @@ +// 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/plugin_ppb_cursor_control.h" + +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/plugin_callback.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/dev/ppb_cursor_control_dev.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" +#include "srpcgen/ppb_rpc.h" + +namespace ppapi_proxy { + +namespace { + +const nacl_abi_size_t kPPPointBytes = + static_cast<nacl_abi_size_t>(sizeof(struct PP_Point)); + +PP_Bool SetCursor(PP_Instance instance, + enum PP_CursorType_Dev type, + PP_Resource custom_image, + const struct PP_Point* hot_spot) { + DebugPrintf("PPB_CursorControl::SetCursor: " + "instance=%"NACL_PRIu32"\n", instance); + + int32_t hot_spot_size = (hot_spot != NULL) ? kPPPointBytes : 0; + int32_t success = 0; + NaClSrpcError srpc_result = + PpbCursorControlRpcClient::PPB_CursorControl_SetCursor( + GetMainSrpcChannel(), + instance, + type, + custom_image, + hot_spot_size, + reinterpret_cast<char*>(const_cast<struct PP_Point*>(hot_spot)), + &success); + + DebugPrintf("PPB_CursorControl::SetCursor: %s\n", + NaClSrpcErrorString(srpc_result)); + if (srpc_result == NACL_SRPC_RESULT_OK && success) + return PP_TRUE; + return PP_FALSE; +} + +PP_Bool LockCursor(PP_Instance instance) { + DebugPrintf("PPB_CursorControl::LockCursor: " + "instance=%"NACL_PRIu32"\n", instance); + + int32_t success = 0; + NaClSrpcError srpc_result = + PpbCursorControlRpcClient::PPB_CursorControl_LockCursor( + GetMainSrpcChannel(), + instance, + &success); + + DebugPrintf("PPB_CursorControl::LockCursor: %s\n", + NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK && success) + return PP_TRUE; + return PP_FALSE; +} + +PP_Bool UnlockCursor(PP_Instance instance) { + DebugPrintf("PPB_CursorControl::UnlockCursor: " + "instance=%"NACL_PRIu32"\n", instance); + + int32_t success = 0; + NaClSrpcError srpc_result = + PpbCursorControlRpcClient::PPB_CursorControl_UnlockCursor( + GetMainSrpcChannel(), + instance, + &success); + + DebugPrintf("PPB_CursorControl::UnlockCursor: %s\n", + NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK && success) + return PP_TRUE; + return PP_FALSE; +} + +PP_Bool HasCursorLock(PP_Instance instance) { + DebugPrintf("PPB_CursorControl::HasCursorLock: " + "instance=%"NACL_PRIu32"\n", instance); + + int32_t success = 0; + NaClSrpcError srpc_result = + PpbCursorControlRpcClient::PPB_CursorControl_HasCursorLock( + GetMainSrpcChannel(), + instance, + &success); + + DebugPrintf("PPB_CursorControl::HasCursorLock: %s\n", + NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK && success) + return PP_TRUE; + return PP_FALSE; +} + +PP_Bool CanLockCursor(PP_Instance instance) { + DebugPrintf("PPB_CursorControl::CanLockCursor: " + "instance=%"NACL_PRIu32"\n", instance); + + int32_t success = 0; + NaClSrpcError srpc_result = + PpbCursorControlRpcClient::PPB_CursorControl_CanLockCursor( + GetMainSrpcChannel(), + instance, + &success); + + DebugPrintf("PPB_CursorControl::CanLockCursor: %s\n", + NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK && success) + return PP_TRUE; + return PP_FALSE; +} + +} // namespace + +const PPB_CursorControl_Dev* PluginCursorControl::GetInterface() { + static const PPB_CursorControl_Dev cursor_control_interface = { + SetCursor, + LockCursor, + UnlockCursor, + HasCursorLock, + CanLockCursor + }; + return &cursor_control_interface; +} + +} // namespace ppapi_proxy + + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_cursor_control.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_cursor_control.h new file mode 100644 index 0000000..392687c --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_cursor_control.h @@ -0,0 +1,26 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_CURSOR_CONTROL_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_CURSOR_CONTROL_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "ppapi/c/dev/ppb_cursor_control_dev.h" + +namespace ppapi_proxy { + +// Implements the untrusted side of the PPB_CursorControl_Dev interface. +class PluginCursorControl { + public: + PluginCursorControl(); + static const PPB_CursorControl_Dev* GetInterface(); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(PluginCursorControl); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_CURSOR_CONTROL_H_ + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_file_io.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_file_io.cc new file mode 100644 index 0000000..a1925fb --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_file_io.cc @@ -0,0 +1,303 @@ +// 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/plugin_ppb_file_io.h" + +#include <string.h> +#include <cmath> + +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/plugin_callback.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_file_info.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/ppb_file_io.h" +#include "srpcgen/ppb_rpc.h" + +namespace ppapi_proxy { + +namespace { + +PP_Resource Create(PP_Instance instance) { + DebugPrintf("PPB_FileIO::Create: instance=%"NACL_PRIu32"\n", instance); + PP_Resource resource = kInvalidResourceId; + NaClSrpcError srpc_result = + PpbFileIORpcClient::PPB_FileIO_Create( + GetMainSrpcChannel(), + instance, + &resource); + + DebugPrintf("PPB_FileIO::Create: %s\n", NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK) + return resource; + return kInvalidResourceId; +} + +PP_Bool IsFileIO(PP_Resource resource) { + DebugPrintf("PPB_FileIO::IsFileIO: resource=%"NACL_PRIu32"\n", resource); + + int32_t is_fileio = 0; + NaClSrpcError srpc_result = + PpbFileIORpcClient::PPB_FileIO_IsFileIO( + GetMainSrpcChannel(), + resource, + &is_fileio); + + DebugPrintf("PPB_FileIO::IsFileIO: %s\n", NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK && is_fileio) + return PP_TRUE; + return PP_FALSE; +} + +int32_t Open(PP_Resource file_io, + PP_Resource file_ref, + int32_t open_flags, + struct PP_CompletionCallback callback) { + DebugPrintf("PPB_FileIO::Open: file_io=%"NACL_PRIu32", " + "file_ref=%"NACL_PRIu32", open_flags=%"NACL_PRId32"\n", file_io, + file_ref, open_flags); + + int32_t callback_id = + CompletionCallbackTable::Get()->AddCallback(callback); + if (callback_id == 0) // Just like Chrome, for now disallow blocking calls. + return PP_ERROR_BADARGUMENT; + + int32_t pp_error; + NaClSrpcError srpc_result = + PpbFileIORpcClient::PPB_FileIO_Open( + GetMainSrpcChannel(), + file_io, + file_ref, + open_flags, + callback_id, + &pp_error); + + DebugPrintf("PPB_FileIO::Open: %s\n", NaClSrpcErrorString(srpc_result)); + + if (srpc_result != NACL_SRPC_RESULT_OK) + pp_error = PP_ERROR_FAILED; + return MayForceCallback(callback, pp_error); +} + +int32_t Query(PP_Resource file_io, + PP_FileInfo* info, + struct PP_CompletionCallback callback) { + DebugPrintf("PPB_FileIO::Query: file_io=%"NACL_PRIu32"\n", file_io); + if (callback.func == 0) // Just like Chrome, for now disallow blocking calls. + return PP_ERROR_BADARGUMENT; + + int32_t callback_id = CompletionCallbackTable::Get()->AddCallback( + callback, reinterpret_cast<char*>(info)); + + nacl_abi_size_t info_size = 0; + int32_t pp_error = PP_ERROR_FAILED; + NaClSrpcError srpc_result = + PpbFileIORpcClient::PPB_FileIO_Query( + GetMainSrpcChannel(), + file_io, + sizeof(PP_FileInfo), + callback_id, + &info_size, + reinterpret_cast<char*>(info), + &pp_error); + + DebugPrintf("PPB_FileIO::Query: %s\n", NaClSrpcErrorString(srpc_result)); + + if (srpc_result != NACL_SRPC_RESULT_OK) + pp_error = PP_ERROR_FAILED; + return MayForceCallback(callback, pp_error); +} + +int32_t Touch(PP_Resource file_io, + PP_Time last_access_time, + PP_Time last_modified_time, + struct PP_CompletionCallback callback) { + DebugPrintf("PPB_FileIO::Touch: file_io=%"NACL_PRIu32", " + "last_access_time=%ls, last_modified_time=%lf\n", file_io, + last_access_time, last_modified_time); + + if (std::isnan(last_access_time) || + std::isnan(last_modified_time)) { + return PP_ERROR_BADARGUMENT; + } + + int32_t callback_id = + CompletionCallbackTable::Get()->AddCallback(callback); + if (callback_id == 0) // Just like Chrome, for now disallow blocking calls. + return PP_ERROR_BADARGUMENT; + + + int32_t pp_error = PP_ERROR_FAILED; + NaClSrpcError srpc_result = PpbFileIORpcClient::PPB_FileIO_Touch( + GetMainSrpcChannel(), + file_io, + last_access_time, + last_modified_time, + callback_id, + &pp_error); + + DebugPrintf("PPB_FileIO::Touch: %s\n", NaClSrpcErrorString(srpc_result)); + + if (srpc_result != NACL_SRPC_RESULT_OK) + pp_error = PP_ERROR_FAILED; + return MayForceCallback(callback, pp_error); +} + +int32_t Read(PP_Resource file_io, + int64_t offset, + char* buffer, + int32_t bytes_to_read, + struct PP_CompletionCallback callback) { + DebugPrintf("PPB_FileIO::Read: file_io=%"NACL_PRIu32", " + "offset=%"NACL_PRId64", bytes_to_read=%"NACL_PRId32"\n", file_io, + offset, bytes_to_read); + + if (bytes_to_read < 0) + bytes_to_read = 0; + nacl_abi_size_t buffer_size = bytes_to_read; + + int32_t callback_id = + CompletionCallbackTable::Get()->AddCallback(callback, buffer); + if (callback_id == 0) // Just like Chrome, for now disallow blocking calls. + return PP_ERROR_BADARGUMENT; + + int32_t pp_error_or_bytes; + NaClSrpcError srpc_result = + PpbFileIORpcClient::PPB_FileIO_Read( + GetMainSrpcChannel(), + file_io, + offset, + bytes_to_read, + callback_id, + &buffer_size, + buffer, + &pp_error_or_bytes); + + DebugPrintf("PPB_FileIO::Read: %s\n", NaClSrpcErrorString(srpc_result)); + + if (srpc_result != NACL_SRPC_RESULT_OK) + pp_error_or_bytes = PP_ERROR_FAILED; + return MayForceCallback(callback, pp_error_or_bytes); +} + +int32_t Write(PP_Resource file_io, + int64_t offset, + const char* buffer, + int32_t bytes_to_write, + struct PP_CompletionCallback callback) { + DebugPrintf("PPB_FileIO::Write: file_io=%"NACL_PRIu32", offset=" + "%"NACL_PRId64", bytes_to_write=%"NACL_PRId32"\n", file_io, + offset, bytes_to_write); + + if (bytes_to_write < 0) + bytes_to_write = 0; + nacl_abi_size_t buffer_size = static_cast<nacl_abi_size_t>(bytes_to_write); + + int32_t callback_id = + CompletionCallbackTable::Get()->AddCallback(callback); + if (callback_id == 0) // Just like Chrome, for now disallow blocking calls. + return PP_ERROR_BADARGUMENT; + + int32_t pp_error_or_bytes = PP_ERROR_FAILED; + NaClSrpcError srpc_result = PpbFileIORpcClient::PPB_FileIO_Write( + GetMainSrpcChannel(), + file_io, + offset, + buffer_size, + const_cast<char*>(buffer), + bytes_to_write, + callback_id, + &pp_error_or_bytes); + + DebugPrintf("PPB_FileIO::Write: %s\n", NaClSrpcErrorString(srpc_result)); + + if (srpc_result != NACL_SRPC_RESULT_OK) + pp_error_or_bytes = PP_ERROR_FAILED; + return MayForceCallback(callback, pp_error_or_bytes); +} + +int32_t SetLength(PP_Resource file_io, + int64_t length, + struct PP_CompletionCallback callback) { + DebugPrintf("PPB_FileIO::SetLength: file_io=%"NACL_PRIu32", length=" + "%"NACL_PRId64"\n", file_io, length); + + int32_t callback_id = + CompletionCallbackTable::Get()->AddCallback(callback); + if (callback_id == 0) // Just like Chrome, for now disallow blocking calls. + return PP_ERROR_BADARGUMENT; + + int32_t pp_error = PP_ERROR_FAILED; + NaClSrpcError srpc_result = PpbFileIORpcClient::PPB_FileIO_SetLength( + GetMainSrpcChannel(), + file_io, + length, + callback_id, + &pp_error); + + DebugPrintf("PPB_FileIO::SetLength: %s\n", + NaClSrpcErrorString(srpc_result)); + + if (srpc_result != NACL_SRPC_RESULT_OK) + pp_error = PP_ERROR_FAILED; + return MayForceCallback(callback, pp_error); +} + +int32_t Flush(PP_Resource file_io, + struct PP_CompletionCallback callback) { + DebugPrintf("PPB_FileIO::Flush: file_io=%"NACL_PRIu32"\n", file_io); + + int32_t callback_id = + CompletionCallbackTable::Get()->AddCallback(callback); + if (callback_id == 0) // Just like Chrome, for now disallow blocking calls. + return PP_ERROR_BADARGUMENT; + + int32_t pp_error = PP_ERROR_FAILED; + NaClSrpcError srpc_result = PpbFileIORpcClient::PPB_FileIO_Flush( + GetMainSrpcChannel(), + file_io, + callback_id, + &pp_error); + + DebugPrintf("PPB_FileIO::Flush: %s\n", NaClSrpcErrorString(srpc_result)); + + if (srpc_result != NACL_SRPC_RESULT_OK) + pp_error = PP_ERROR_FAILED; + return MayForceCallback(callback, pp_error); +} + +void Close(PP_Resource file_io) { + DebugPrintf("PPB_FileIO::Close: file_io=%"NACL_PRIu32"\n", file_io); + + NaClSrpcError srpc_result = PpbFileIORpcClient::PPB_FileIO_Close( + GetMainSrpcChannel(), + file_io); + + DebugPrintf("PPB_FileIO::Close: %s\n", NaClSrpcErrorString(srpc_result)); +} + +} // namespace + +const PPB_FileIO* PluginFileIO::GetInterface() { + static const PPB_FileIO file_io_interface = { + Create, + IsFileIO, + Open, + Query, + Touch, + Read, + Write, + SetLength, + Flush, + Close + }; + return &file_io_interface; +} + +} // namespace ppapi_proxy diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_file_io.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_file_io.h new file mode 100644 index 0000000..7cf30c9 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_file_io.h @@ -0,0 +1,23 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_FILE_IO_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_FILE_IO_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "ppapi/c/ppb_file_io.h" + +namespace ppapi_proxy { + +// Implements the untrusted side of the PPB_FileIO interface. +class PluginFileIO { + public: + static const PPB_FileIO* GetInterface(); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(PluginFileIO); +}; +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_FILE_IO_H_ diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_file_ref.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_file_ref.cc new file mode 100644 index 0000000..1506a24 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_file_ref.cc @@ -0,0 +1,256 @@ +// 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/plugin_ppb_file_ref.h" + +#include <string.h> +#include <cmath> +#include <string> + +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/object_serialize.h" +#include "native_client/src/shared/ppapi_proxy/plugin_callback.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" +#include "srpcgen/ppb_rpc.h" + +namespace ppapi_proxy { + +namespace { +bool IsDirectoryTraversal(const std::string& path) { + bool is_directory_traversal = true; + // TODO(sanga): Do we need to guard against percent encoded strings as well? + if (path.find("../") == std::string::npos) + is_directory_traversal = false; + return is_directory_traversal; +} + +PP_Resource Create(PP_Resource file_system, + const char* path) { + DebugPrintf("PPB_FileRef::Create: file_system=%"NACL_PRIu32", path=%s\n", + file_system, path); + + PP_Resource resource = kInvalidResourceId; + + if (IsDirectoryTraversal(path)) + return kInvalidResourceId; + + NaClSrpcError srpc_result = PpbFileRefRpcClient::PPB_FileRef_Create( + GetMainSrpcChannel(), + file_system, + strlen(path) + 1, // Add 1 to preserve terminating '\0' + const_cast<char*>(path), + &resource); + DebugPrintf("PPB_FileRef::Create: %s\n", NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK) + return resource; + return kInvalidResourceId; +} + +PP_Bool IsFileRef(PP_Resource file_ref) { + DebugPrintf("PPB_FileRef::IsFileRef: file_ref=%"NACL_PRIu32"\n", file_ref); + + int32_t is_file_ref = 0; + NaClSrpcError srpc_result = PpbFileRefRpcClient::PPB_FileRef_IsFileRef( + GetMainSrpcChannel(), + file_ref, + &is_file_ref); + DebugPrintf("PPB_FileRef::IsFileRef: %s\n", NaClSrpcErrorString(srpc_result)); + + if ((srpc_result == NACL_SRPC_RESULT_OK) && is_file_ref) + return PP_TRUE; + return PP_FALSE; +} + +PP_FileSystemType GetFileSystemType(PP_Resource file_ref) { + DebugPrintf("PPB_FileRef::GetFileSystemType: file_ref=%"NACL_PRIu32"\n", + file_ref); + + int32_t file_system_type = PP_FILESYSTEMTYPE_INVALID; + NaClSrpcError srpc_result = + PpbFileRefRpcClient::PPB_FileRef_GetFileSystemType( + GetMainSrpcChannel(), + file_ref, + &file_system_type); + DebugPrintf("PPB_FileRef::GetFileSystemType: %s\n", + NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK) + return static_cast<PP_FileSystemType>(file_system_type); + return PP_FILESYSTEMTYPE_INVALID; +} + +PP_Var GetName(PP_Resource file_ref) { + DebugPrintf("PPB_FileRef::GetName: file_ref=%"NACL_PRIu32"\n", file_ref); + + PP_Var name = PP_MakeUndefined(); + nacl_abi_size_t length = kMaxVarSize; + nacl::scoped_array<char> name_bytes(new char[length]); + NaClSrpcError srpc_result = PpbFileRefRpcClient::PPB_FileRef_GetName( + GetMainSrpcChannel(), + file_ref, + &length, + name_bytes.get()); + DebugPrintf("PPB_FileRef::GetName: %s\n", NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK) { + if (DeserializeTo(GetMainSrpcChannel(), name_bytes.get(), length, + 1, // argc + &name)) + return name; + } + return PP_MakeUndefined(); +} + +PP_Var GetPath(PP_Resource file_ref) { + DebugPrintf("PPB_FileRef::GetPath: file_ref=%"NACL_PRIu32"\n", file_ref); + + PP_Var path = PP_MakeUndefined(); + nacl_abi_size_t length = kMaxVarSize; + nacl::scoped_array<char> path_bytes(new char[length]); + NaClSrpcError srpc_result = PpbFileRefRpcClient::PPB_FileRef_GetPath( + GetMainSrpcChannel(), + file_ref, + &length, + path_bytes.get()); + DebugPrintf("PPB_FileRef::GetPath: %s\n", + NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK && + DeserializeTo(GetMainSrpcChannel(), path_bytes.get(), length, + 1, // argc + &path)) { + return path; + } + return PP_MakeUndefined(); +} + +PP_Resource GetParent(PP_Resource file_ref) { + DebugPrintf("PPB_FileRef::GetParent: file_ref=%"NACL_PRIu32"\n", file_ref); + + PP_Resource parent = kInvalidResourceId; + NaClSrpcError srpc_result = PpbFileRefRpcClient::PPB_FileRef_GetParent( + GetMainSrpcChannel(), + file_ref, + &parent); + DebugPrintf("PPB_FileRef::GetParent: %s\n", + NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK) + return parent; + return kInvalidResourceId; +} + +int32_t MakeDirectory(PP_Resource directory_ref, + PP_Bool make_ancestors, + struct PP_CompletionCallback callback) { + DebugPrintf("PPB_FileRef::MakeDirectory: directory_ref=%"NACL_PRIu32", " + "make_ancestors=%s\n", directory_ref, + (make_ancestors ? "true" : "false")); + + int32_t callback_id = CompletionCallbackTable::Get()->AddCallback(callback); + int32_t pp_error = PP_ERROR_FAILED; + NaClSrpcError srpc_result = PpbFileRefRpcClient::PPB_FileRef_MakeDirectory( + GetMainSrpcChannel(), + directory_ref, + make_ancestors, + callback_id, + &pp_error); + DebugPrintf("PPB_FileRef::MakeDirectory: %s\n", + NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK) + return MayForceCallback(callback, pp_error); + return PP_ERROR_FAILED; +} + +int32_t Touch(PP_Resource file_ref, + PP_Time last_access_time, + PP_Time last_modified_time, + struct PP_CompletionCallback callback) { + DebugPrintf("PPB_FileRef::Touch: file_ref=%"NACL_PRIu32", " + "last_access_time=%lf, last_modified_time=%lf\n", + file_ref, last_access_time, last_modified_time); + + if (std::isnan(last_access_time) || + std::isnan(last_modified_time)) { + return PP_ERROR_FAILED; + } + + int32_t callback_id = CompletionCallbackTable::Get()->AddCallback(callback); + int32_t pp_error = PP_ERROR_FAILED; + NaClSrpcError srpc_result = PpbFileRefRpcClient::PPB_FileRef_Touch( + GetMainSrpcChannel(), + file_ref, + last_access_time, + last_modified_time, + callback_id, + &pp_error); + DebugPrintf("PPB_FileRef::Touch: %s\n", NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK) + return MayForceCallback(callback, pp_error); + return PP_ERROR_FAILED; +} + +int32_t Delete(PP_Resource file_ref, + struct PP_CompletionCallback callback) { + DebugPrintf("PPB_FileRef::Delete: file_ref=%"NACL_PRIu32"\n", file_ref); + + int32_t callback_id = CompletionCallbackTable::Get()->AddCallback(callback); + int32_t pp_error = PP_ERROR_FAILED; + NaClSrpcError srpc_result = PpbFileRefRpcClient::PPB_FileRef_Delete( + GetMainSrpcChannel(), + file_ref, + callback_id, + &pp_error); + DebugPrintf("PPB_FileRef::Delete: %s\n", NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK) + return MayForceCallback(callback, pp_error); + return PP_ERROR_FAILED; +} + +int32_t Rename(PP_Resource file_ref, + PP_Resource new_file_ref, + struct PP_CompletionCallback callback) { + DebugPrintf("PPB_FileRef::Rename: file_ref=%"NACL_PRIu32", " + "new_file_ref=%"NACL_PRIu32"\n", file_ref, new_file_ref); + + int32_t callback_id = CompletionCallbackTable::Get()->AddCallback(callback); + int32_t pp_error = PP_ERROR_FAILED; + NaClSrpcError srpc_result = PpbFileRefRpcClient::PPB_FileRef_Rename( + GetMainSrpcChannel(), + file_ref, + new_file_ref, + callback_id, + &pp_error); + DebugPrintf("PPB_FileRef::Rename: %s\n", NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK) + return MayForceCallback(callback, pp_error); + return PP_ERROR_FAILED; +} +} // namespace + +const PPB_FileRef* PluginFileRef::GetInterface() { + static const PPB_FileRef file_ref_interface = { + Create, + IsFileRef, + GetFileSystemType, + GetName, + GetPath, + GetParent, + MakeDirectory, + Touch, + Delete, + Rename + }; + return &file_ref_interface; +} +} // namespace ppapi_proxy diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_file_ref.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_file_ref.h new file mode 100644 index 0000000..1ac516b --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_file_ref.h @@ -0,0 +1,24 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_FILE_REF_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_FILE_REF_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "ppapi/c/ppb_file_ref.h" + +namespace ppapi_proxy { + +// Implements the untrusted side of the PPB_FileRef interface. +class PluginFileRef { + public: + static const PPB_FileRef* GetInterface(); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(PluginFileRef); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_FILE_REF_H_ diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_file_system.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_file_system.cc new file mode 100644 index 0000000..0fca300 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_file_system.cc @@ -0,0 +1,105 @@ +// 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/plugin_ppb_file_system.h" + +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/plugin_callback.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" +#include "srpcgen/ppb_rpc.h" + +namespace ppapi_proxy { + +namespace { + +PP_Resource Create(PP_Instance instance, PP_FileSystemType type) { + DebugPrintf("PPB_FileSystem::Create: instance=%"NACL_PRIu32" " + "type=%"NACL_PRIu32"\n", + instance, type); + PP_Resource pp_resource = kInvalidResourceId; + NaClSrpcError srpc_result = + PpbFileSystemRpcClient::PPB_FileSystem_Create( + GetMainSrpcChannel(), + instance, + type, + &pp_resource); + DebugPrintf("PPB_FileSystem::Create: %s\n", + NaClSrpcErrorString(srpc_result)); + if (srpc_result == NACL_SRPC_RESULT_OK) + return pp_resource; + return kInvalidResourceId; +} + +PP_Bool IsFileSystem(PP_Resource resource) { + DebugPrintf("PPB_FileSystem::IsFileSystem: resource=%"NACL_PRIu32"\n", + resource); + int32_t is_file_system = 0; + NaClSrpcError srpc_result = + PpbFileSystemRpcClient::PPB_FileSystem_IsFileSystem( + GetMainSrpcChannel(), + resource, + &is_file_system); + DebugPrintf("PPB_FileSystem::IsFileSystem: %s\n", + NaClSrpcErrorString(srpc_result)); + if (NACL_SRPC_RESULT_OK != srpc_result) { + return PP_FALSE; + } + return PP_FromBool(is_file_system); +} + +int32_t Open(PP_Resource file_system, + int64_t expected_size, + struct PP_CompletionCallback callback) { + DebugPrintf("PPB_FileSystem::Open: file_system=%"NACL_PRIu32"\n", + file_system); + int32_t callback_id = CompletionCallbackTable::Get()->AddCallback(callback); + if (callback_id == 0) + return PP_ERROR_BADARGUMENT; + + int32_t pp_error; + NaClSrpcError srpc_result = + PpbFileSystemRpcClient::PPB_FileSystem_Open( + GetMainSrpcChannel(), + file_system, + expected_size, + callback_id, + &pp_error); + DebugPrintf("PPB_FileSystem::Open: %s\n", + NaClSrpcErrorString(srpc_result)); + if (srpc_result != NACL_SRPC_RESULT_OK) + pp_error = PP_ERROR_FAILED; + return MayForceCallback(callback, pp_error); +} + +PP_FileSystemType GetType(PP_Resource file_system) { + DebugPrintf("PPB_FileSystem::GetType: file_system=%"NACL_PRIu32"\n", + file_system); + int32_t type = PP_FILESYSTEMTYPE_INVALID; + NaClSrpcError srpc_result = + PpbFileSystemRpcClient::PPB_FileSystem_GetType( + GetMainSrpcChannel(), + file_system, + &type); + DebugPrintf("PPB_FileSystem::GetType: %s\n", + NaClSrpcErrorString(srpc_result)); + if (srpc_result == NACL_SRPC_RESULT_OK) + return static_cast<PP_FileSystemType>(type); + return PP_FILESYSTEMTYPE_INVALID; +} + +} // namespace + +const PPB_FileSystem* PluginFileSystem::GetInterface() { + static const PPB_FileSystem file_system_interface = { + Create, + IsFileSystem, + Open, + GetType + }; + return &file_system_interface; +} +} // namespace ppapi_proxy diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_file_system.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_file_system.h new file mode 100644 index 0000000..cad51bf --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_file_system.h @@ -0,0 +1,23 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_FILE_SYSTEM_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_FILE_SYSTEM_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "ppapi/c/ppb_file_system.h" + +namespace ppapi_proxy { + +// Implements the untrusted side of the PPB_FileSystem interface. +class PluginFileSystem { + public: + static const PPB_FileSystem* GetInterface(); + private: + NACL_DISALLOW_COPY_AND_ASSIGN(PluginFileSystem); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_FILE_SYSTEM_H_ diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_find.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_find.cc new file mode 100644 index 0000000..5030863 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_find.cc @@ -0,0 +1,64 @@ +// 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/plugin_ppb_find.h" + +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/plugin_callback.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/dev/ppb_find_dev.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" +#include "srpcgen/ppb_rpc.h" + +namespace ppapi_proxy { + +namespace { + +void NumberOfFindResultsChanged(PP_Instance instance, + int32_t total, + PP_Bool final_result) { + DebugPrintf("PPB_Find::NumberOfFindResultsChanged: " + "instance=%"NACL_PRIu32"\n", instance); + + NaClSrpcError srpc_result = + PpbFindRpcClient::PPB_Find_NumberOfFindResultsChanged( + GetMainSrpcChannel(), + instance, + total, + final_result == PP_TRUE); + + DebugPrintf("PPB_Find::NumberOfFindResultsChanged: %s\n", + NaClSrpcErrorString(srpc_result)); +} + +void SelectedFindResultChanged(PP_Instance instance, + int32_t index) { + DebugPrintf("PPB_Find::SelectedFindResultChanged: " + "instance=%"NACL_PRIu32"\n", instance); + + NaClSrpcError srpc_result = + PpbFindRpcClient::PPB_Find_SelectedFindResultChanged( + GetMainSrpcChannel(), + instance, + index); + + DebugPrintf("PPB_Find::SelectedFindResultChanged: %s\n", + NaClSrpcErrorString(srpc_result)); +} + +} // namespace + +const PPB_Find_Dev* PluginFind::GetInterface() { + static const PPB_Find_Dev find_interface = { + NumberOfFindResultsChanged, + SelectedFindResultChanged + }; + return &find_interface; +} + +} // namespace ppapi_proxy + + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_find.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_find.h new file mode 100644 index 0000000..7ce74c3 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_find.h @@ -0,0 +1,26 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_FIND_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_FIND_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "ppapi/c/dev/ppb_find_dev.h" + +namespace ppapi_proxy { + +// Implements the untrusted side of the PPB_Find_Dev interface. +class PluginFind { + public: + PluginFind(); + static const PPB_Find_Dev* GetInterface(); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(PluginFind); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_FIND_H_ + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_font.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_font.cc new file mode 100644 index 0000000..0f9a911 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_font.cc @@ -0,0 +1,270 @@ +// 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/plugin_ppb_font.h" + +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/object_serialize.h" +#include "native_client/src/shared/ppapi_proxy/plugin_callback.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/dev/ppb_font_dev.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_point.h" +#include "ppapi/c/pp_rect.h" +#include "srpcgen/ppb_rpc.h" + +namespace ppapi_proxy { + +namespace { + +const nacl_abi_size_t kPPPointBytes = + static_cast<nacl_abi_size_t>(sizeof(struct PP_Point)); +const nacl_abi_size_t kPPRectBytes = + static_cast<nacl_abi_size_t>(sizeof(struct PP_Rect)); +const nacl_abi_size_t kPPTextRunBytes = + static_cast<nacl_abi_size_t>(sizeof(struct PP_TextRun_Dev)); +const nacl_abi_size_t kPPFontMetricsBytes = + static_cast<nacl_abi_size_t>(sizeof(struct PP_FontMetrics_Dev)); +const nacl_abi_size_t kPPFontDescriptionBytes = + static_cast<nacl_abi_size_t>(sizeof(struct PP_FontDescription_Dev)); +const int32_t kInvalidOffset = -1; + +PP_Var GetFontFamilies(PP_Instance instance) { + DebugPrintf("PPB_Font::GetFontFamilies: instance=%"NACL_PRIu32"\n", + instance); + NaClSrpcChannel* channel = GetMainSrpcChannel(); + + PP_Var font_families = PP_MakeUndefined(); + nacl_abi_size_t var_size = kMaxVarSize; + nacl::scoped_array<char> var_bytes(new char[kMaxVarSize]); + + NaClSrpcError srpc_result = + PpbFontRpcClient::PPB_Font_GetFontFamilies( + channel, + instance, + &var_size, + var_bytes.get()); + + DebugPrintf("PPB_Font::GetFontFamilies: %s\n", + NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK) + (void) DeserializeTo( + channel, var_bytes.get(), var_size, 1, &font_families); + return font_families; +} + +PP_Resource Create(PP_Instance instance, + const struct PP_FontDescription_Dev* description) { + DebugPrintf("PPB_Font::Create: instance=%"NACL_PRIu32"\n", instance); + + nacl_abi_size_t face_size = kMaxVarSize; + nacl::scoped_array<char> face_bytes( + Serialize(&description->face, 1, &face_size)); + + PP_Resource resource = kInvalidResourceId; + NaClSrpcError srpc_result = + PpbFontRpcClient::PPB_Font_Create( + GetMainSrpcChannel(), + instance, + kPPFontDescriptionBytes, + reinterpret_cast<char*>( + const_cast<struct PP_FontDescription_Dev*>(description)), + face_size, + face_bytes.get(), + &resource); + + DebugPrintf("PPB_Font::Create: %s\n", NaClSrpcErrorString(srpc_result)); + if (srpc_result == NACL_SRPC_RESULT_OK) { + scoped_refptr<PluginFont> font = + PluginResource::AdoptAs<PluginFont>(resource); + if (font.get()) + return resource; + } + return kInvalidResourceId; +} + +PP_Bool IsFont(PP_Resource resource) { + DebugPrintf("PPB_Font::IsFont: resource=%"NACL_PRIu32"\n", resource); + + int32_t is_font = 0; + NaClSrpcError srpc_result = + PpbFontRpcClient::PPB_Font_IsFont(GetMainSrpcChannel(), + resource, + &is_font); + + DebugPrintf("PPB_Font::IsFont: %s\n", NaClSrpcErrorString(srpc_result)); + if (srpc_result == NACL_SRPC_RESULT_OK && is_font) + return PP_TRUE; + return PP_FALSE; +} + +PP_Bool Describe(PP_Resource font, + struct PP_FontDescription_Dev* description, + struct PP_FontMetrics_Dev* metrics) { + DebugPrintf("PPB_Font::Describe: font=%"NACL_PRIu32"\n", font); + NaClSrpcChannel* channel = GetMainSrpcChannel(); + + int32_t success = 0; + nacl_abi_size_t description_size = kPPFontDescriptionBytes; + nacl_abi_size_t face_size = kMaxVarSize; + nacl::scoped_array<char> face_bytes(new char[kMaxVarSize]); + nacl_abi_size_t metrics_size = kPPFontMetricsBytes; + NaClSrpcError srpc_result = + PpbFontRpcClient::PPB_Font_Describe( + channel, + font, + &description_size, + reinterpret_cast<char*>(description), + &face_size, + face_bytes.get(), + &metrics_size, + reinterpret_cast<char*>(metrics), + &success); + + DebugPrintf("PPB_Font::Describe: %s\n", NaClSrpcErrorString(srpc_result)); + + description->face = PP_MakeUndefined(); + if (srpc_result == NACL_SRPC_RESULT_OK && success) { + (void) DeserializeTo( + channel, face_bytes.get(), face_size, 1, &description->face); + return PP_TRUE; + } + return PP_FALSE; +} + +PP_Bool DrawTextAt(PP_Resource font, + PP_Resource image_data, + const struct PP_TextRun_Dev* text_run, + const struct PP_Point* position, + uint32_t color, + const struct PP_Rect* clip, + PP_Bool image_data_is_opaque) { + DebugPrintf("PPB_Font::DrawTextAt: font=%"NACL_PRIu32"\n", font); + + nacl_abi_size_t text_size = kMaxVarSize; + nacl::scoped_array<char> text_bytes( + Serialize(&text_run->text, 1, &text_size)); + + int32_t success = 0; + NaClSrpcError srpc_result = + PpbFontRpcClient::PPB_Font_DrawTextAt( + GetMainSrpcChannel(), + font, + image_data, + kPPTextRunBytes, + reinterpret_cast<char*>( + const_cast<struct PP_TextRun_Dev*>(text_run)), + text_size, + text_bytes.get(), + kPPPointBytes, + reinterpret_cast<char*>(const_cast<struct PP_Point*>(position)), + color, + kPPRectBytes, + reinterpret_cast<char*>(const_cast<struct PP_Rect*>(clip)), + image_data_is_opaque, + &success); + + DebugPrintf("PPB_Font::DrawTextAt: %s\n", NaClSrpcErrorString(srpc_result)); + if (srpc_result == NACL_SRPC_RESULT_OK && success) + return PP_TRUE; + return PP_FALSE; +} + +int32_t MeasureText(PP_Resource font, + const struct PP_TextRun_Dev* text_run) { + DebugPrintf("PPB_Font::MeasureText: font=%"NACL_PRIu32"\n", font); + + nacl_abi_size_t text_size = kMaxVarSize; + nacl::scoped_array<char> text_bytes( + Serialize(&text_run->text, 1, &text_size)); + int32_t width = 0; + NaClSrpcError srpc_result = + PpbFontRpcClient::PPB_Font_MeasureText( + GetMainSrpcChannel(), + font, + kPPTextRunBytes, + reinterpret_cast<char*>( + const_cast<struct PP_TextRun_Dev*>(text_run)), + text_size, + text_bytes.get(), + &width); + + DebugPrintf("PPB_Font::MeasureText: %s\n", NaClSrpcErrorString(srpc_result)); + return width; +} + +uint32_t CharacterOffsetForPixel(PP_Resource font, + const struct PP_TextRun_Dev* text_run, + int32_t pixel_position) { + DebugPrintf("PPB_Font::CharacterOffsetForPixel: font=%"NACL_PRIu32"\n", font); + + nacl_abi_size_t text_size = kMaxVarSize; + nacl::scoped_array<char> text_bytes( + Serialize(&text_run->text, 1, &text_size)); + int32_t offset = kInvalidOffset; + NaClSrpcError srpc_result = + PpbFontRpcClient::PPB_Font_CharacterOffsetForPixel( + GetMainSrpcChannel(), + font, + kPPTextRunBytes, + reinterpret_cast<char*>( + const_cast<struct PP_TextRun_Dev*>(text_run)), + text_size, + text_bytes.get(), + pixel_position, + &offset); + + DebugPrintf("PPB_Font::CharacterOffsetForPixel: %s\n", + NaClSrpcErrorString(srpc_result)); + return offset; +} + +int32_t PixelOffsetForCharacter(PP_Resource font, + const struct PP_TextRun_Dev* text_run, + uint32_t char_offset) { + DebugPrintf("PPB_Font::PixelOffsetForCharacter: font=%"NACL_PRIu32"\n", font); + + nacl_abi_size_t text_size = kMaxVarSize; + nacl::scoped_array<char> text_bytes( + Serialize(&text_run->text, 1, &text_size)); + int32_t offset = kInvalidOffset; + NaClSrpcError srpc_result = + PpbFontRpcClient::PPB_Font_PixelOffsetForCharacter( + GetMainSrpcChannel(), + font, + kPPTextRunBytes, + reinterpret_cast<char*>( + const_cast<struct PP_TextRun_Dev*>(text_run)), + text_size, + text_bytes.get(), + char_offset, + &offset); + + DebugPrintf("PPB_Font::PixelOffsetForCharacter: %s\n", + NaClSrpcErrorString(srpc_result)); + return offset; +} + +} // namespace + +const PPB_Font_Dev* PluginFont::GetInterface() { + static const PPB_Font_Dev font_interface = { + GetFontFamilies, + Create, + IsFont, + Describe, + DrawTextAt, + MeasureText, + CharacterOffsetForPixel, + PixelOffsetForCharacter + }; + return &font_interface; +} + +} // namespace ppapi_proxy + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_font.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_font.h new file mode 100644 index 0000000..d0c6dc6 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_font.h @@ -0,0 +1,29 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_FONT_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_FONT_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/shared/ppapi_proxy/plugin_resource.h" +#include "ppapi/c/dev/ppb_font_dev.h" + +namespace ppapi_proxy { + +// Implements the untrusted side of the PPB_Font_Dev interface. +class PluginFont : public PluginResource { + public: + PluginFont() {} + virtual bool InitFromBrowserResource(PP_Resource resource) { return true; } + + static const PPB_Font_Dev* GetInterface(); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(PluginFont); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_FONT_H_ + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_graphics_2d.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_graphics_2d.cc new file mode 100644 index 0000000..ccb4f94 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_graphics_2d.cc @@ -0,0 +1,183 @@ +// 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/plugin_ppb_graphics_2d.h" + +#include <stdio.h> +#include <string.h> +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/plugin_callback.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/plugin_upcall.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_rect.h" +#include "ppapi/c/pp_size.h" +#include "ppapi/c/ppb_graphics_2d.h" +#include "srpcgen/ppb_rpc.h" +#include "srpcgen/upcall.h" + +namespace ppapi_proxy { + +namespace { + +const nacl_abi_size_t kPPSizeBytes = + static_cast<nacl_abi_size_t>(sizeof(struct PP_Size)); +const nacl_abi_size_t kPPPointBytes = + static_cast<nacl_abi_size_t>(sizeof(struct PP_Point)); +const nacl_abi_size_t kPPRectBytes = + static_cast<nacl_abi_size_t>(sizeof(struct PP_Rect)); + +PP_Resource Create(PP_Instance instance, + const struct PP_Size* size, + PP_Bool is_always_opaque) { + DebugPrintf("PPB_Graphics2D::Create: instance=%"NACL_PRIu32"\n", instance); + char* size_as_char_ptr = + reinterpret_cast<char*>(const_cast<struct PP_Size*>(size)); + int32_t is_always_opaque_as_int = static_cast<int32_t>(is_always_opaque); + PP_Resource resource = kInvalidResourceId; + NaClSrpcError srpc_result = + PpbGraphics2DRpcClient::PPB_Graphics2D_Create( + GetMainSrpcChannel(), + instance, + kPPSizeBytes, + size_as_char_ptr, + is_always_opaque_as_int, + &resource); + DebugPrintf("PPB_Graphics2D::Create: %s\n", NaClSrpcErrorString(srpc_result)); + if (srpc_result == NACL_SRPC_RESULT_OK) { + scoped_refptr<PluginGraphics2D> graphics_2d = + PluginResource::AdoptAs<PluginGraphics2D>(resource); + if (graphics_2d.get()) { + return resource; + } + } + return kInvalidResourceId; +} + +PP_Bool IsGraphics2D(PP_Resource resource) { + DebugPrintf("PPB_Graphics2D::IsGraphics2D: resource=%"NACL_PRIu32"\n", + resource); + return PluginResource::GetAs<PluginGraphics2D>(resource).get() + ? PP_TRUE : PP_FALSE; +} + +PP_Bool Describe(PP_Resource graphics_2d, + struct PP_Size* size, + PP_Bool* is_always_opaque) { + DebugPrintf("PPB_Graphics2D::Describe: graphics_2d=%"NACL_PRIu32"\n", + graphics_2d); + if (size == NULL || is_always_opaque == NULL) { + return PP_FALSE; + } + int32_t is_always_opaque_as_int; + nacl_abi_size_t size_ret = kPPSizeBytes; + int32_t result; + NaClSrpcError srpc_result = + PpbGraphics2DRpcClient::PPB_Graphics2D_Describe( + GetMainSrpcChannel(), + graphics_2d, + &size_ret, + reinterpret_cast<char*>(size), + &is_always_opaque_as_int, + &result); + DebugPrintf("PPB_Graphics2D::Describe: %s\n", + NaClSrpcErrorString(srpc_result)); + if (srpc_result == NACL_SRPC_RESULT_OK || size_ret != kPPSizeBytes) { + *is_always_opaque = is_always_opaque_as_int ? PP_TRUE : PP_FALSE; + return result ? PP_TRUE : PP_FALSE; + } else { + return PP_FALSE; + } +} + +void PaintImageData(PP_Resource graphics_2d, + PP_Resource image, + const struct PP_Point* top_left, + const struct PP_Rect* src_rect) { + DebugPrintf("PPB_Graphics2D::PaintImageData: graphics_2d=%"NACL_PRIu32"\n", + graphics_2d); + nacl_abi_size_t rect_size = kPPRectBytes; + if (src_rect == NULL) { // Corresponds to the entire image. + rect_size = 0; + } + NaClSrpcError srpc_result = + PpbGraphics2DRpcClient::PPB_Graphics2D_PaintImageData( + GetMainSrpcChannel(), + graphics_2d, + image, + kPPPointBytes, + reinterpret_cast<char*>(const_cast<struct PP_Point*>(top_left)), + rect_size, + reinterpret_cast<char*>(const_cast<struct PP_Rect*>(src_rect))); + DebugPrintf("PPB_Graphics2D::PaintImageData: %s\n", + NaClSrpcErrorString(srpc_result)); +} + +void Scroll(PP_Resource graphics_2d, + const struct PP_Rect* clip_rect, + const struct PP_Point* amount) { + DebugPrintf("PPB_Graphics2D::Scroll: graphics_2d=%"NACL_PRIu32"\n", + graphics_2d); + nacl_abi_size_t rect_size = kPPRectBytes; + if (clip_rect == NULL) { // Corresponds to the entire graphics region. + rect_size = 0; + } + NaClSrpcError srpc_result = PpbGraphics2DRpcClient::PPB_Graphics2D_Scroll( + GetMainSrpcChannel(), + graphics_2d, + rect_size, + reinterpret_cast<char*>(const_cast<struct PP_Rect*>(clip_rect)), + kPPPointBytes, + reinterpret_cast<char*>(const_cast<struct PP_Point*>(amount))); + DebugPrintf("PPB_Graphics2D::Scroll: %s\n", NaClSrpcErrorString(srpc_result)); +} + +void ReplaceContents(PP_Resource graphics_2d, PP_Resource image) { + DebugPrintf("PPB_Graphics2D::ReplaceContents: graphics_2d=%"NACL_PRIu32"\n", + graphics_2d); + NaClSrpcError srpc_result = + PpbGraphics2DRpcClient::PPB_Graphics2D_ReplaceContents( + GetMainSrpcChannel(), graphics_2d, image); + DebugPrintf("PPB_Graphics2D::ReplaceContents: %s\n", + NaClSrpcErrorString(srpc_result)); +} + +int32_t Flush(PP_Resource graphics_2d, + struct PP_CompletionCallback callback) { + DebugPrintf("PPB_Graphics2D::Flush: graphics_2d=%"NACL_PRIu32"\n", + graphics_2d); + int32_t callback_id = + CompletionCallbackTable::Get()->AddCallback(callback); + if (callback_id == 0) // Just like Chrome, for now disallow blocking calls. + return PP_ERROR_BADARGUMENT; + + int32_t pp_error; + NaClSrpcError srpc_result = + PpbGraphics2DRpcClient::PPB_Graphics2D_Flush( + GetMainSrpcChannel(), graphics_2d, callback_id, &pp_error); + DebugPrintf("PPB_Graphics2D::Flush: %s\n", NaClSrpcErrorString(srpc_result)); + if (srpc_result != NACL_SRPC_RESULT_OK) + pp_error = PP_ERROR_FAILED; + return MayForceCallback(callback, pp_error); +} + +} // namespace + +const PPB_Graphics2D* PluginGraphics2D::GetInterface() { + static const PPB_Graphics2D graphics_2d_interface = { + Create, + IsGraphics2D, + Describe, + PaintImageData, + Scroll, + ReplaceContents, + Flush, + }; + return &graphics_2d_interface; +} + +} // namespace ppapi_proxy diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_graphics_2d.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_graphics_2d.h new file mode 100644 index 0000000..e262e8c --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_graphics_2d.h @@ -0,0 +1,29 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_GRAPHICS_2D_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_GRAPHICS_2D_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/shared/ppapi_proxy/plugin_resource.h" +#include "ppapi/c/ppb_graphics_2d.h" + +namespace ppapi_proxy { + +// Implements the untrusted side of the PPB_Graphics2D interface. +class PluginGraphics2D : public PluginResource { + public: + PluginGraphics2D() {} + bool InitFromBrowserResource(PP_Resource resource) { return true; } + + static const PPB_Graphics2D* GetInterface(); + + private: + IMPLEMENT_RESOURCE(PluginGraphics2D); + NACL_DISALLOW_COPY_AND_ASSIGN(PluginGraphics2D); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_GRAPHICS_2D_H_ diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_graphics_3d.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_graphics_3d.cc new file mode 100644 index 0000000..78f6986 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_graphics_3d.cc @@ -0,0 +1,239 @@ +/* + * 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/plugin_ppb_graphics_3d.h" + +#include "gpu/command_buffer/client/gles2_implementation.h" +#include "native_client/src/shared/ppapi_proxy/command_buffer_nacl.h" +#include "native_client/src/shared/ppapi_proxy/object_serialize.h" +#include "native_client/src/shared/ppapi_proxy/plugin_callback.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/plugin_instance_data.h" +#include "native_client/src/shared/ppapi_proxy/plugin_ppb_core.h" +#include "native_client/src/shared/ppapi_proxy/plugin_ppb_var.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_rect.h" +#include "ppapi/c/pp_var.h" +#include "srpcgen/ppb_rpc.h" + +namespace ppapi_proxy { + +namespace { + +const int32 kRingBufferSize = 4096 * 1024; +const int32 kTransferBufferSize = 4096 * 1024; + +int32_t GetNumAttribs(const int32_t* attrib_list) { + int32_t num = 0; + if (attrib_list) { + // skip over attrib pairs + while (attrib_list[num] != PP_GRAPHICS3DATTRIB_NONE) + num += 2; + // Add one more for PP_GRAPHICS3DATTRIB_NONE. + num += 1; + } + return num; +} + +PP_Resource Create(PP_Instance instance, + PP_Resource share_context, + const int32_t* attrib_list) { + DebugPrintf("PPB_Graphics3D::Create: instance=%"NACL_PRIu32"\n", instance); + PP_Resource graphics3d_id = kInvalidResourceId; + nacl_abi_size_t num_attribs = GetNumAttribs(attrib_list); + NaClSrpcError retval = + PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_CreateRaw( + GetMainSrpcChannel(), + instance, + share_context, + num_attribs, const_cast<int32_t *>(attrib_list), + &graphics3d_id); + if (retval == NACL_SRPC_RESULT_OK) { + scoped_refptr<PluginGraphics3D> graphics_3d = + PluginResource::AdoptAs<PluginGraphics3D>(graphics3d_id); + if (graphics_3d.get()) { + graphics_3d->set_instance_id(instance); + return graphics3d_id; + } + } + return kInvalidResourceId; +} + +PP_Bool IsGraphics3D(PP_Resource resource) { + DebugPrintf("PPB_Graphics3D::IsGraphics3D: resource=%"NACL_PRIu32"\n", + resource); + return PluginResource::GetAs<PluginGraphics3D>(resource).get() + ? PP_TRUE : PP_FALSE; +} + +int32_t GetAttribs(PP_Resource graphics3d_id, + int32_t* attrib_list) { + int32_t pp_error; + nacl_abi_size_t num_attribs = GetNumAttribs(attrib_list); + NaClSrpcError retval = + PpbGraphics3DRpcClient::PPB_Graphics3D_GetAttribs( + GetMainSrpcChannel(), + graphics3d_id, + num_attribs, attrib_list, + &num_attribs, attrib_list, + &pp_error); + if (retval != NACL_SRPC_RESULT_OK) { + return PP_ERROR_BADARGUMENT; + } + return pp_error; +} + +int32_t SetAttribs(PP_Resource graphics3d_id, + int32_t* attrib_list) { + int32_t pp_error; + nacl_abi_size_t num_attribs = GetNumAttribs(attrib_list); + NaClSrpcError retval = + PpbGraphics3DRpcClient::PPB_Graphics3D_SetAttribs( + GetMainSrpcChannel(), + graphics3d_id, + num_attribs, attrib_list, + &pp_error); + if (retval != NACL_SRPC_RESULT_OK) { + return PP_ERROR_BADARGUMENT; + } + return pp_error; +} + +int32_t ResizeBuffers(PP_Resource graphics3d_id, + int32_t width, + int32_t height) { + int32_t pp_error; + NaClSrpcError retval = + PpbGraphics3DRpcClient::PPB_Graphics3D_ResizeBuffers( + GetMainSrpcChannel(), + graphics3d_id, + width, + height, + &pp_error); + if (retval != NACL_SRPC_RESULT_OK) { + return PP_ERROR_BADARGUMENT; + } + return pp_error; +} + + +int32_t SwapBuffs(PP_Resource graphics3d_id, + struct PP_CompletionCallback callback) { + DebugPrintf("PPB_Graphics3D::SwapBuffers: graphics3d_id=%"NACL_PRIu32"\n", + graphics3d_id); + + scoped_refptr<PluginGraphics3D> graphics3d = + PluginResource::GetAs<PluginGraphics3D>(graphics3d_id).get(); + if (!graphics3d.get()) + return MayForceCallback(callback, PP_ERROR_BADRESOURCE); + + return MayForceCallback(callback, + graphics3d->SwapBuffers(graphics3d_id, callback)); +} + +} // namespace + +__thread PP_Resource PluginGraphics3D::cached_graphics3d_id = 0; +__thread gpu::gles2::GLES2Implementation* + PluginGraphics3D::cached_implementation = NULL; + +PluginGraphics3D::PluginGraphics3D() : instance_id_(0) { } + +PluginGraphics3D::~PluginGraphics3D() { + // Invalidate the cache. + cached_graphics3d_id = 0; + cached_implementation = NULL; +} + +// static +gpu::gles2::GLES2Implementation* PluginGraphics3D::implFromResourceSlow( + PP_Resource graphics3d_id) { + DebugPrintf("PluginGraphics3D::implFromResourceSlow: " + "resource=%"NACL_PRIu32"\n", graphics3d_id); + + // For performance reasons, we don't error-check the context, but crash on + // NULL instead. + gpu::gles2::GLES2Implementation* impl = + PluginResource::GetAs<PluginGraphics3D>(graphics3d_id)->impl(); + cached_graphics3d_id = graphics3d_id; + cached_implementation = impl; + return impl; +} + + +bool PluginGraphics3D::InitFromBrowserResource(PP_Resource res) { + DebugPrintf("PluginGraphics3D::InitFromBrowserResource: " + "resource=%"NACL_PRIu32"\n", res); + + // Create and initialize the objects required to issue GLES2 calls. + command_buffer_.reset(new CommandBufferNacl(res, PluginCore::GetInterface())); + command_buffer_->Initialize(kRingBufferSize); + gles2_helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer_.get())); + gpu::Buffer buffer = command_buffer_->GetRingBuffer(); + DebugPrintf("PluginGraphics3D::InitFromBrowserResource: buffer size: %d\n", + buffer.size); + if (gles2_helper_->Initialize(buffer.size)) { + // Request id -1 to signify 'don't care' + int32 transfer_buffer_id = + command_buffer_->CreateTransferBuffer(kTransferBufferSize, -1); + gpu::Buffer transfer_buffer = + command_buffer_->GetTransferBuffer(transfer_buffer_id); + if (transfer_buffer.ptr) { + gles2_implementation_.reset(new gpu::gles2::GLES2Implementation( + gles2_helper_.get(), + transfer_buffer.size, + transfer_buffer.ptr, + transfer_buffer_id, + false)); + return true; + } + } + return false; +} + +int32_t PluginGraphics3D::SwapBuffers(PP_Resource graphics3d_id, + struct PP_CompletionCallback callback) { + + int32_t callback_id = CompletionCallbackTable::Get()->AddCallback(callback); + if (callback_id == 0) // Just like Chrome, for now disallow blocking calls. + return PP_ERROR_BADARGUMENT; + + int32_t pp_error; + NaClSrpcError retval = + PpbGraphics3DRpcClient::PPB_Graphics3D_SwapBuffers( + GetMainSrpcChannel(), + graphics3d_id, + callback_id, + &pp_error); + if (retval != NACL_SRPC_RESULT_OK) + return PP_ERROR_FAILED; + + if ((PP_OK_COMPLETIONPENDING != pp_error) && (PP_OK != pp_error)) + return pp_error; + + impl()->SwapBuffers(); + return PP_OK_COMPLETIONPENDING; +} + + +// static +const PPB_Graphics3D_Dev* PluginGraphics3D::GetInterface() { + static const PPB_Graphics3D_Dev intf = { + &Create, + &IsGraphics3D, + &GetAttribs, + &SetAttribs, + &ResizeBuffers, + &SwapBuffs, + }; + return &intf; +} + +} // namespace ppapi_proxy + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_graphics_3d.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_graphics_3d.h new file mode 100644 index 0000000..63c3bca --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_graphics_3d.h @@ -0,0 +1,77 @@ +/* + * Copyright 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. + */ + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_GRAPHICS_3D_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_GRAPHICS_3D_H_ + +#include "base/scoped_ptr.h" +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/shared/ppapi_proxy/plugin_resource.h" +#include "ppapi/c/dev/pp_graphics_3d_dev.h" +#include "ppapi/c/dev/ppb_graphics_3d_dev.h" +#include "ppapi/c/dev/ppb_opengles_dev.h" +#include "ppapi/c/pp_instance.h" + +namespace gpu { +class CommandBuffer; +namespace gles2 { +class GLES2CmdHelper; +class GLES2Implementation; +} // namespace gles2 +} // namespace gpu + +namespace ppapi_proxy { + +// Implements the plugin (i.e., .nexe) side of the PPB_Graphics3D interface. +class PluginGraphics3D : public PluginResource { + public: + PluginGraphics3D(); + virtual ~PluginGraphics3D(); + + static const PPB_Graphics3D_Dev* GetInterface(); + static const PPB_OpenGLES2_Dev* GetOpenGLESInterface(); + + virtual bool InitFromBrowserResource(PP_Resource graphics3d_id); + + gpu::gles2::GLES2Implementation* impl() { + return gles2_implementation_.get(); + } + + int32_t SwapBuffers(PP_Resource graphics3d_id, + struct PP_CompletionCallback callback); + + PP_Instance instance_id() { return instance_id_; } + void set_instance_id(PP_Instance instance_id) { instance_id_ = instance_id; } + + static inline gpu::gles2::GLES2Implementation* implFromResource( + PP_Resource graphics3d_id) { + if (cached_graphics3d_id == graphics3d_id && cached_implementation != NULL) + return cached_implementation; + + return implFromResourceSlow(graphics3d_id); + } + + + private: + static __thread PP_Resource cached_graphics3d_id; + static __thread gpu::gles2::GLES2Implementation* cached_implementation; + + // GLES2 Implementation objects. + scoped_ptr<gpu::CommandBuffer> command_buffer_; + scoped_ptr<gpu::gles2::GLES2Implementation> gles2_implementation_; + scoped_ptr<gpu::gles2::GLES2CmdHelper> gles2_helper_; + PP_Instance instance_id_; + + static gpu::gles2::GLES2Implementation* implFromResourceSlow( + PP_Resource context); + + IMPLEMENT_RESOURCE(PluginGraphics3D); + NACL_DISALLOW_COPY_AND_ASSIGN(PluginGraphics3D); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_GRAPHICS_3D_H_ diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_image_data.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_image_data.cc new file mode 100644 index 0000000..24b46f1 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_image_data.cc @@ -0,0 +1,179 @@ +// Copyright 2010 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/plugin_ppb_image_data.h" + +#include <stdio.h> +#include <string.h> +#include <sys/mman.h> +#include "srpcgen/ppb_rpc.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "ppapi/c/ppb_image_data.h" + +namespace ppapi_proxy { + +namespace { + +// round size up to next 64k +size_t ceil64k(size_t n) { + return (n + 0xFFFF) & (~0xFFFF); +} + +PP_ImageDataFormat GetNativeImageDataFormat() { + DebugPrintf("PPB_ImageData::GetNativeImageDataFormat\n"); + int32_t format; + NaClSrpcError srpc_result = + PpbImageDataRpcClient::PPB_ImageData_GetNativeImageDataFormat( + GetMainSrpcChannel(), + &format); + DebugPrintf("PPB_ImageData::GetNativeImageDataFormat: %s\n", + NaClSrpcErrorString(srpc_result)); + if (srpc_result == NACL_SRPC_RESULT_OK) { + return static_cast<PP_ImageDataFormat>(format); + } else { + return PP_IMAGEDATAFORMAT_BGRA_PREMUL; + } +} + +PP_Bool IsImageDataFormatSupported(PP_ImageDataFormat format) { + DebugPrintf("PPB_ImageData::IsImageDataFormatSupported: format=%" + NACL_PRId32"\n", static_cast<int32_t>(format)); + int32_t result; + NaClSrpcError srpc_result = + PpbImageDataRpcClient::PPB_ImageData_IsImageDataFormatSupported( + GetMainSrpcChannel(), + static_cast<int32_t>(format), + &result); + DebugPrintf("PPB_ImageData::IsImageDataFormatSupported: %s\n", + NaClSrpcErrorString(srpc_result)); + if (srpc_result == NACL_SRPC_RESULT_OK) { + return (result ? PP_TRUE : PP_FALSE); + } else { + return PP_FALSE; + } +} + +PP_Resource Create(PP_Instance instance, + PP_ImageDataFormat format, + const struct PP_Size* size, + PP_Bool init_to_zero) { + DebugPrintf("PPB_ImageData::Create: instance=%"NACL_PRIu32"\n", instance); + PP_Resource resource; + NaClSrpcError srpc_result = + PpbImageDataRpcClient::PPB_ImageData_Create( + GetMainSrpcChannel(), + instance, + static_cast<int32_t>(format), + static_cast<nacl_abi_size_t>(sizeof(struct PP_Size)), + reinterpret_cast<char*>(const_cast<struct PP_Size*>(size)), + (init_to_zero == PP_TRUE), + &resource); + DebugPrintf("PPB_ImageData::Create: %s\n", NaClSrpcErrorString(srpc_result)); + if (srpc_result == NACL_SRPC_RESULT_OK) { + scoped_refptr<PluginImageData> image_data = + PluginResource::AdoptAs<PluginImageData>(resource); + if (image_data.get()) { + return resource; + } + } + return kInvalidResourceId; +} + +PP_Bool IsImageData(PP_Resource resource) { + DebugPrintf("PPB_ImageData::IsImageData: resource=%"NACL_PRIu32"\n", + resource); + return PluginResource::GetAs<PluginImageData>(resource).get() + ? PP_TRUE : PP_FALSE; +} + +PP_Bool Describe(PP_Resource resource, + struct PP_ImageDataDesc* desc) { + DebugPrintf("PPB_ImageData::Describe: resource=%"NACL_PRIu32"\n", + resource); + scoped_refptr<PluginImageData> imagedata = + PluginResource::GetAs<PluginImageData>(resource); + if (!imagedata.get()) { + return PP_FALSE; + } + + *desc = imagedata->desc(); + return PP_TRUE; +} + +void* DoMap(PP_Resource resource) { + DebugPrintf("PPB_ImageData::DoMap: resource=%"NACL_PRIu32"\n", resource); + scoped_refptr<PluginImageData> imagedata = + PluginResource::GetAs<PluginImageData>(resource); + + return imagedata.get() ? imagedata->Map() : NULL; +} + +void DoUnmap(PP_Resource resource) { + DebugPrintf("PPB_ImageData::DoUnmap: resource=%"NACL_PRIu32"\n", resource); + scoped_refptr<PluginImageData> imagedata = + PluginResource::GetAs<PluginImageData>(resource); + if (imagedata.get()) + imagedata->Unmap(); +} + +} // namespace + +const PPB_ImageData* PluginImageData::GetInterface() { + static const PPB_ImageData image_data_interface = { + &GetNativeImageDataFormat, + &IsImageDataFormatSupported, + &Create, + &IsImageData, + &Describe, + &DoMap, + &DoUnmap, + }; + return &image_data_interface; +} + +PluginImageData::PluginImageData() + : shm_size_(0), + addr_(NULL) { +} + +bool PluginImageData::InitFromBrowserResource(PP_Resource resource) { + nacl_abi_size_t desc_size = static_cast<nacl_abi_size_t>(sizeof(desc_)); + int32_t success = PP_FALSE; + + NaClSrpcError result = + PpbImageDataRpcClient::PPB_ImageData_Describe( + GetMainSrpcChannel(), + resource, + &desc_size, + reinterpret_cast<char*>(&desc_), + &shm_fd_, + &shm_size_, + &success); + return (NACL_SRPC_RESULT_OK == result) && (PP_TRUE == success); +} + +void* PluginImageData::Map() { + if (NULL != addr_) { + return addr_; + } + if (!shm_size_) { + return NULL; + } + + addr_ = mmap(0, ceil64k(shm_size_), PROT_READ | PROT_WRITE, + MAP_SHARED, shm_fd_, 0); + return addr_; +} + +void PluginImageData::Unmap() { + if (addr_) { + munmap(addr_, ceil64k(shm_size_)); + addr_ = NULL; + } +} + +} // namespace ppapi_proxy diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_image_data.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_image_data.h new file mode 100644 index 0000000..92be59c --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_image_data.h @@ -0,0 +1,36 @@ +// Copyright 2010 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_IMAGE_DATA_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_IMAGE_DATA_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/shared/ppapi_proxy/plugin_resource.h" +#include "ppapi/c/ppb_image_data.h" + +namespace ppapi_proxy { + +// Implements the untrusted side of the PPB_ImageData interface. +class PluginImageData : public PluginResource { + public: + PluginImageData(); + static const PPB_ImageData* GetInterface(); + + bool InitFromBrowserResource(PP_Resource resource); + void* Map(); + void Unmap(); + + const PP_ImageDataDesc& desc() const { return desc_; } + private: + IMPLEMENT_RESOURCE(PluginImageData); + NACL_DISALLOW_COPY_AND_ASSIGN(PluginImageData); + PP_ImageDataDesc desc_; + int shm_fd_; + int32_t shm_size_; + void* addr_; +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_IMAGE_DATA_H_ diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_input_event.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_input_event.cc new file mode 100644 index 0000000..d9e15d8 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_input_event.cc @@ -0,0 +1,404 @@ +// 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/plugin_ppb_input_event.h" + +#include <stdio.h> +#include <string.h> + +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/object_serialize.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/plugin_resource.h" +#include "native_client/src/shared/ppapi_proxy/untrusted/srpcgen/ppb_rpc.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/ppb_input_event.h" + +namespace { + +using ppapi_proxy::DebugPrintf; +using ppapi_proxy::GetMainSrpcChannel; +using ppapi_proxy::kInvalidResourceId; +using ppapi_proxy::kMaxVarSize; +using ppapi_proxy::PluginInputEvent; +using ppapi_proxy::PluginResource; +using ppapi_proxy::Serialize; + +// InputEvent ------------------------------------------------------------------ + +int32_t RequestInputEvents(PP_Instance instance, uint32_t event_classes) { + DebugPrintf("PPB_InputEvent::RequestInputEvents: instance=%"NACL_PRIu32", " + "event_classes=%"NACL_PRIu32"\n", + instance, event_classes); + uint32_t success = 0; + NaClSrpcError srpc_result = + PpbInputEventRpcClient::PPB_InputEvent_RequestInputEvents( + GetMainSrpcChannel(), + instance, + static_cast<int32_t>(event_classes), + false, // false -> Don't filter. + reinterpret_cast<int32_t*>(&success)); + if (srpc_result == NACL_SRPC_RESULT_OK) { + return success; + } + return PP_ERROR_FAILED; +} + +int32_t RequestFilteringInputEvents(PP_Instance instance, + uint32_t event_classes) { + DebugPrintf("PPB_InputEvent::RequestFilteringInputEvents: instance=" + "%"NACL_PRIu32", event_classes=%"NACL_PRIu32"\n", + instance, event_classes); + uint32_t success = 0; + NaClSrpcError srpc_result = + PpbInputEventRpcClient::PPB_InputEvent_RequestInputEvents( + GetMainSrpcChannel(), + instance, + static_cast<int32_t>(event_classes), + true, // true -> Filter. + reinterpret_cast<int32_t*>(&success)); + if (srpc_result == NACL_SRPC_RESULT_OK) { + return success; + } + return PP_ERROR_FAILED; +} + +void ClearInputEventRequest(PP_Instance instance, + uint32_t event_classes) { + DebugPrintf("PPB_InputEvent::ClearInputEventRequest: instance=%"NACL_PRIu32 + ", event_classes=%"NACL_PRIu32"\n", + instance, event_classes); + PpbInputEventRpcClient::PPB_InputEvent_ClearInputEventRequest( + GetMainSrpcChannel(), + instance, + static_cast<int32_t>(event_classes)); +} + +// Helper RAII class to get the PluginInputEvent from the PP_Resource and hold +// it with a scoped_refptr. Also does a DebugPrintf. +class InputEventGetter { + public: + InputEventGetter(PP_Resource resource, const char* function_name) { + DebugPrintf("PPB_InputEvent::%s: resource=%"NACL_PRIu32"\n", + function_name, + resource); + input_event_ = + PluginResource::GetAs<PluginInputEvent>(resource); + } + + PluginInputEvent* get() { + return input_event_.get(); + } + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(InputEventGetter); + scoped_refptr<PluginInputEvent> input_event_; +}; +// This macro is for starting a resource function. It makes sure resource_arg +// is of type PluginInputEvent, and returns error_return if it's not. +#define BEGIN_RESOURCE_THUNK(function_name, resource_arg, error_return) \ + InputEventGetter input_event(resource_arg, function_name); \ + if (!input_event.get()) { \ + return error_return; \ + } \ + do {} while(0) + +PP_Bool IsInputEvent(PP_Resource resource) { + BEGIN_RESOURCE_THUNK("IsInputEvent", resource, PP_FALSE); + return PP_TRUE; +} + +#define IMPLEMENT_RESOURCE_THUNK(function, resource_arg, error_return) \ + BEGIN_RESOURCE_THUNK(#function, resource_arg, error_return); \ + return input_event.get()->function() + +PP_InputEvent_Type GetType(PP_Resource event) { + IMPLEMENT_RESOURCE_THUNK(GetType, event, PP_INPUTEVENT_TYPE_UNDEFINED); +} + +PP_TimeTicks GetTimeStamp(PP_Resource event) { + IMPLEMENT_RESOURCE_THUNK(GetTimeStamp, event, 0.0); +} + +uint32_t GetModifiers(PP_Resource event) { + IMPLEMENT_RESOURCE_THUNK(GetModifiers, event, 0); +} + +// Mouse ----------------------------------------------------------------------- + +PP_Resource CreateMouseInputEvent(PP_Instance instance, + PP_InputEvent_Type type, + PP_TimeTicks time_stamp, + uint32_t modifiers, + PP_InputEvent_MouseButton mouse_button, + const PP_Point* mouse_position, + int32_t click_count) { + DebugPrintf("PPB_InputEvent::CreateMouseInputEvent: instance=" + "%"NACL_PRIu32", type=%d, time_stamp=%lf, modifiers=" + "%"NACL_PRIu32", mouse_button=%d, x=%"NACL_PRId32", y=" + "%"NACL_PRId32", click_count=%d\n", + instance, type, time_stamp, modifiers, mouse_button, + mouse_position->x, mouse_position->y, click_count); + PP_Resource resource_id = kInvalidResourceId; + NaClSrpcError srpc_result = + PpbInputEventRpcClient::PPB_InputEvent_CreateMouseInputEvent( + GetMainSrpcChannel(), + instance, + static_cast<int32_t>(type), + time_stamp, + static_cast<int32_t>(modifiers), + static_cast<int32_t>(mouse_button), + mouse_position->x, + mouse_position->y, + click_count, + &resource_id); + if (srpc_result == NACL_SRPC_RESULT_OK) + return resource_id; + return kInvalidResourceId; +} + +PP_Bool IsMouseInputEvent(PP_Resource resource) { + if (!IsInputEvent(resource)) + return PP_FALSE; + PP_InputEvent_Type type = GetType(resource); + return PP_FromBool(type == PP_INPUTEVENT_TYPE_MOUSEDOWN || + type == PP_INPUTEVENT_TYPE_MOUSEUP || + type == PP_INPUTEVENT_TYPE_MOUSEMOVE || + type == PP_INPUTEVENT_TYPE_MOUSEENTER || + type == PP_INPUTEVENT_TYPE_MOUSELEAVE || + type == PP_INPUTEVENT_TYPE_CONTEXTMENU); +} + +PP_InputEvent_MouseButton GetMouseButton(PP_Resource mouse_event) { + IMPLEMENT_RESOURCE_THUNK(GetMouseButton, mouse_event, + PP_INPUTEVENT_MOUSEBUTTON_NONE); +} + +PP_Point GetMousePosition(PP_Resource mouse_event) { + IMPLEMENT_RESOURCE_THUNK(GetMousePosition, mouse_event, PP_MakePoint(0, 0)); +} + +int32_t GetMouseClickCount(PP_Resource mouse_event) { + IMPLEMENT_RESOURCE_THUNK(GetMouseClickCount, mouse_event, 0); +} + +// Wheel ----------------------------------------------------------------------- + +PP_Resource CreateWheelInputEvent(PP_Instance instance, + PP_TimeTicks time_stamp, + uint32_t modifiers, + const PP_FloatPoint* wheel_delta, + const PP_FloatPoint* wheel_ticks, + PP_Bool scroll_by_page) { + DebugPrintf("PPB_InputEvent::CreateWheelInputEvent: instance=" + "%"NACL_PRIu32", time_stamp=%lf, modifiers=" + "%"NACL_PRIu32", delta.x=%d, delta.y=%d, ticks.x=%d, ticks.y=%d, " + "scroll_by_page=%s\n", + instance, time_stamp, modifiers, wheel_delta->x, wheel_delta->y, + wheel_ticks->x, wheel_ticks->y, + (scroll_by_page ? "true" : "false")); + PP_Resource resource_id = kInvalidResourceId; + NaClSrpcError srpc_result = + PpbInputEventRpcClient::PPB_InputEvent_CreateWheelInputEvent( + GetMainSrpcChannel(), + instance, + static_cast<double>(time_stamp), + static_cast<int32_t>(modifiers), + wheel_delta->x, + wheel_delta->y, + wheel_ticks->x, + wheel_ticks->y, + static_cast<int32_t>(scroll_by_page), + &resource_id); + if (srpc_result == NACL_SRPC_RESULT_OK) + return resource_id; + return kInvalidResourceId; +} + +PP_Bool IsWheelInputEvent(PP_Resource resource) { + if (!IsInputEvent(resource)) + return PP_FALSE; + PP_InputEvent_Type type = GetType(resource); + return PP_FromBool(type == PP_INPUTEVENT_TYPE_WHEEL); +} + +PP_FloatPoint GetWheelDelta(PP_Resource wheel_event) { + IMPLEMENT_RESOURCE_THUNK(GetWheelDelta, wheel_event, PP_MakeFloatPoint(0, 0)); +} + +PP_FloatPoint GetWheelTicks(PP_Resource wheel_event) { + IMPLEMENT_RESOURCE_THUNK(GetWheelTicks, wheel_event, PP_MakeFloatPoint(0, 0)); +} + +PP_Bool GetWheelScrollByPage(PP_Resource wheel_event) { + IMPLEMENT_RESOURCE_THUNK(GetWheelScrollByPage, wheel_event, PP_FALSE); +} + +PP_Resource CreateKeyboardInputEvent(PP_Instance instance, + PP_InputEvent_Type type, + PP_TimeTicks time_stamp, + uint32_t modifiers, + uint32_t key_code, + struct PP_Var character_text) { + DebugPrintf("PPB_InputEvent::CreateKeyboardInputEvent: instance=" + "%"NACL_PRIu32", type=%d, time_stamp=%lf, modifiers=" + "%"NACL_PRIu32", key_code=%"NACL_PRIu32"\n", + instance, type, time_stamp, modifiers, key_code); + // Serialize the character_text Var. + uint32_t text_size = kMaxVarSize; + nacl::scoped_array<char> text_bytes(Serialize(&character_text, 1, + &text_size)); + PP_Resource resource_id = kInvalidResourceId; + NaClSrpcError srpc_result = + PpbInputEventRpcClient::PPB_InputEvent_CreateKeyboardInputEvent( + GetMainSrpcChannel(), + instance, + static_cast<int32_t>(type), + static_cast<double>(time_stamp), + static_cast<int32_t>(modifiers), + static_cast<int32_t>(key_code), + text_size, + text_bytes.get(), + &resource_id); + if (srpc_result == NACL_SRPC_RESULT_OK) + return resource_id; + return kInvalidResourceId; +} + +PP_Bool IsKeyboardInputEvent(PP_Resource resource) { + if (!IsInputEvent(resource)) + return PP_FALSE; + PP_InputEvent_Type type = GetType(resource); + return PP_FromBool(type == PP_INPUTEVENT_TYPE_KEYDOWN || + type == PP_INPUTEVENT_TYPE_KEYUP || + type == PP_INPUTEVENT_TYPE_CHAR); +} + +uint32_t GetKeyCode(PP_Resource key_event) { + IMPLEMENT_RESOURCE_THUNK(GetKeyCode, key_event, 0); +} + +PP_Var GetCharacterText(PP_Resource character_event) { + IMPLEMENT_RESOURCE_THUNK(GetCharacterText, character_event, + PP_MakeUndefined()); +} + +} // namespace + +namespace ppapi_proxy { + +// static +const PPB_InputEvent* PluginInputEvent::GetInterface() { + static const PPB_InputEvent input_event_interface = { + RequestInputEvents, + RequestFilteringInputEvents, + ClearInputEventRequest, + IsInputEvent, + ::GetType, + ::GetTimeStamp, + ::GetModifiers + }; + return &input_event_interface; +} + +// static +const PPB_MouseInputEvent* PluginInputEvent::GetMouseInterface() { + static const PPB_MouseInputEvent mouse_input_event_interface = { + CreateMouseInputEvent, + IsMouseInputEvent, + ::GetMouseButton, + ::GetMousePosition, + ::GetMouseClickCount + }; + return &mouse_input_event_interface; +} + +// static +const PPB_WheelInputEvent* PluginInputEvent::GetWheelInterface() { + static const PPB_WheelInputEvent wheel_input_event_interface = { + CreateWheelInputEvent, + IsWheelInputEvent, + ::GetWheelDelta, + ::GetWheelTicks, + ::GetWheelScrollByPage + }; + return &wheel_input_event_interface; +} + +// static +const PPB_KeyboardInputEvent* PluginInputEvent::GetKeyboardInterface() { + static const PPB_KeyboardInputEvent keyboard_input_event_interface = { + CreateKeyboardInputEvent, + IsKeyboardInputEvent, + ::GetKeyCode, + ::GetCharacterText + }; + return &keyboard_input_event_interface; +} + +PluginInputEvent::PluginInputEvent() + : character_text_(PP_MakeUndefined()) { +} + +void PluginInputEvent::Init(const InputEventData& input_event_data, + PP_Var character_text) { + input_event_data_ = input_event_data; + character_text_ = character_text; +} + +PluginInputEvent::~PluginInputEvent() { + // Release the character text. This is a no-op if it's not a string. + PPBVarInterface()->Release(character_text_); +} + +PP_InputEvent_Type PluginInputEvent::GetType() const { + return input_event_data_.event_type; +} + +PP_TimeTicks PluginInputEvent::GetTimeStamp() const { + return input_event_data_.event_time_stamp; +} + +uint32_t PluginInputEvent::GetModifiers() const { + return input_event_data_.event_modifiers; +} + +PP_InputEvent_MouseButton PluginInputEvent::GetMouseButton() const { + return input_event_data_.mouse_button; +} + +PP_Point PluginInputEvent::GetMousePosition() const { + return input_event_data_.mouse_position; +} + +int32_t PluginInputEvent::GetMouseClickCount() const { + return input_event_data_.mouse_click_count; +} + +PP_FloatPoint PluginInputEvent::GetWheelDelta() const { + return input_event_data_.wheel_delta; +} + +PP_FloatPoint PluginInputEvent::GetWheelTicks() const { + return input_event_data_.wheel_ticks; +} + +PP_Bool PluginInputEvent::GetWheelScrollByPage() const { + return input_event_data_.wheel_scroll_by_page; +} + +uint32_t PluginInputEvent::GetKeyCode() const { + return input_event_data_.key_code; +} + +PP_Var PluginInputEvent::GetCharacterText() const { + PPBVarInterface()->AddRef(character_text_); + return character_text_; +} + +} // namespace ppapi_proxy + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_input_event.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_input_event.h new file mode 100644 index 0000000..b22346d --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_input_event.h @@ -0,0 +1,59 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_INPUT_EVENT_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_INPUT_EVENT_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/shared/ppapi_proxy/input_event_data.h" +#include "native_client/src/shared/ppapi_proxy/plugin_resource.h" +#include "ppapi/c/ppb_input_event.h" + +namespace ppapi_proxy { + +// Implements the untrusted side of the PPB_InputEvent interface. +class PluginInputEvent : public PluginResource { + public: + PluginInputEvent(); + // Init the PluginInputEvent resource with the given data. Assumes + // character_text has been AddRefed if it's a string, and takes ownership. + void Init(const InputEventData& input_event_data, PP_Var character_text); + virtual ~PluginInputEvent(); + + // PluginResource implementation. + virtual bool InitFromBrowserResource(PP_Resource /*resource*/) { + return true; + } + + static const PPB_InputEvent* GetInterface(); + static const PPB_MouseInputEvent* GetMouseInterface(); + static const PPB_WheelInputEvent* GetWheelInterface(); + static const PPB_KeyboardInputEvent* GetKeyboardInterface(); + + PP_InputEvent_Type GetType() const; + PP_TimeTicks GetTimeStamp() const; + uint32_t GetModifiers() const; + + PP_InputEvent_MouseButton GetMouseButton() const; + PP_Point GetMousePosition() const; + int32_t GetMouseClickCount() const; + + PP_FloatPoint GetWheelDelta() const; + PP_FloatPoint GetWheelTicks() const; + PP_Bool GetWheelScrollByPage() const; + + uint32_t GetKeyCode() const; + PP_Var GetCharacterText() const; + + private: + IMPLEMENT_RESOURCE(PluginInputEvent); + NACL_DISALLOW_COPY_AND_ASSIGN(PluginInputEvent); + + InputEventData input_event_data_; + PP_Var character_text_; // Undefined if this is not a character event. +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_INPUT_EVENT_H_ diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_instance.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_instance.cc new file mode 100644 index 0000000..ff6e072 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_instance.cc @@ -0,0 +1,69 @@ +// 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/plugin_ppb_instance.h" + +#include <stdio.h> +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/object_serialize.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "ppapi/c/ppb_instance.h" +#include "srpcgen/ppb_rpc.h" + +namespace ppapi_proxy { + +namespace { + +PP_Bool BindGraphics(PP_Instance instance, PP_Resource device) { + DebugPrintf("PPB_Instance::BindGraphics: instance=%"NACL_PRIu32 + " device=%"NACL_PRIu32"\n", instance, device); + int32_t success = 0; + + NaClSrpcError srpc_result = + PpbInstanceRpcClient::PPB_Instance_BindGraphics( + GetMainSrpcChannel(), + instance, + device, + &success); + DebugPrintf("PPB_Instance::BindGraphics: %s\n", + NaClSrpcErrorString(srpc_result)); + if (srpc_result == NACL_SRPC_RESULT_OK && success) + return PP_TRUE; + else + return PP_FALSE; +} + +PP_Bool IsFullFrame(PP_Instance instance) { + DebugPrintf("PPB_Instance::IsFullFrame: instance=%"NACL_PRIu32"\n", + instance); + int32_t is_full_frame = 0; + + NaClSrpcError srpc_result = + PpbInstanceRpcClient::PPB_Instance_IsFullFrame( + GetMainSrpcChannel(), + instance, + &is_full_frame); + DebugPrintf("PPB_Instance::IsFullFrame: %s\n", + NaClSrpcErrorString(srpc_result)); + if (srpc_result == NACL_SRPC_RESULT_OK && is_full_frame) + return PP_TRUE; + else + return PP_FALSE; +} + +} // namespace + +const PPB_Instance* PluginInstance::GetInterface() { + static const PPB_Instance instance_interface = { + BindGraphics, + IsFullFrame + }; + return &instance_interface; +} + +} // namespace ppapi_proxy diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_instance.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_instance.h new file mode 100644 index 0000000..b051de9 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_instance.h @@ -0,0 +1,24 @@ +// Copyright 2010 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_INSTANCE_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_INSTANCE_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "ppapi/c/ppb_instance.h" + +namespace ppapi_proxy { + +// Implements the untrusted side of the PPB_Instance interface. +class PluginInstance { + public: + static const PPB_Instance* GetInterface(); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(PluginInstance); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_INSTANCE_H_ diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_memory.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_memory.cc new file mode 100644 index 0000000..b00711d --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_memory.cc @@ -0,0 +1,37 @@ +// 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/plugin_ppb_memory.h" + +#include <cstdlib> + +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/dev/ppb_memory_dev.h" + +namespace ppapi_proxy { + +namespace { + +void* MemAlloc(uint32_t num_bytes) { + DebugPrintf("PPB_Memory_Dev::MemAlloc(%"NACL_PRIu32")\n", num_bytes); + return std::malloc(num_bytes); +} + +void MemFree(void* ptr) { + DebugPrintf("PPB_Memory_Dev::MemFree(%p)\n", ptr); + std::free(ptr); +} + +} // namespace + +const PPB_Memory_Dev* PluginMemory::GetInterface() { + static const PPB_Memory_Dev memory_interface = { + MemAlloc, + MemFree + }; + return &memory_interface; +} + +} // namespace ppapi_proxy diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_memory.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_memory.h new file mode 100644 index 0000000..b04d9dd --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_memory.h @@ -0,0 +1,27 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_MEMORY_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_MEMORY_H_ + +#include "native_client/src/include/nacl_macros.h" + +struct PPB_Memory_Dev; + +namespace ppapi_proxy { + +// Implements the plugin side of the PPB_Memory_Dev interface. +class PluginMemory { + public: + // Returns an interface pointer suitable to the PPAPI client. + static const PPB_Memory_Dev* GetInterface(); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(PluginMemory); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_MEMORY_H_ + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_messaging.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_messaging.cc new file mode 100644 index 0000000..b2e0342 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_messaging.cc @@ -0,0 +1,49 @@ +// 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/plugin_ppb_messaging.h" + +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/object_serialize.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_var.h" +#include "srpcgen/ppb_rpc.h" + +namespace ppapi_proxy { + +namespace { + +void PostMessage(PP_Instance instance, struct PP_Var message) { + DebugPrintf("PPB_Messaging::PostMessage: instance=%"NACL_PRIu32"\n", + instance); + if (!ppapi_proxy::PPBCoreInterface()->IsMainThread()) + return; // Only supported on main thread. + + uint32_t message_length = kMaxVarSize; + nacl::scoped_array<char> message_bytes(Serialize(&message, 1, + &message_length)); + NaClSrpcError srpc_result = + PpbMessagingRpcClient::PPB_Messaging_PostMessage( + GetMainSrpcChannel(), + instance, + message_length, + message_bytes.get()); + DebugPrintf("PPB_Messaging::PostMessage: %s\n", + NaClSrpcErrorString(srpc_result)); +} + +} // namespace + +const PPB_Messaging* PluginMessaging::GetInterface() { + static const PPB_Messaging messaging_interface = { + PostMessage + }; + return &messaging_interface; +} + +} // namespace ppapi_proxy diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_messaging.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_messaging.h new file mode 100644 index 0000000..6fe867c --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_messaging.h @@ -0,0 +1,25 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_MESSAGING_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_MESSAGING_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "ppapi/c/ppb_messaging.h" + +namespace ppapi_proxy { + +// Implements the untrusted side of the PPB_Messaging interface. +class PluginMessaging { + public: + static const PPB_Messaging* GetInterface(); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(PluginMessaging); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_MESSAGING_H_ + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_pdf.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_pdf.cc new file mode 100644 index 0000000..87be470 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_pdf.cc @@ -0,0 +1,255 @@ +// 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/plugin_ppb_pdf.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/mman.h> + +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/object_serialize.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/plugin_ppb_image_data.h" +#include "native_client/src/shared/ppapi_proxy/plugin_resource.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "ppapi/c/private/ppb_pdf.h" +#include "srpcgen/ppb_rpc.h" + +namespace ppapi_proxy { + +namespace { + +const nacl_abi_size_t kPpbPrivateFindResultBytes = + static_cast<nacl_abi_size_t>(sizeof(PP_PrivateFindResult)); +// Limit the maximum result buffer size. +const nacl_abi_size_t kMaxFindResultsBytes = 65536; +const int32_t kMaxFindResults = + kMaxFindResultsBytes / kPpbPrivateFindResultBytes; + +PP_Var GetLocalizedString( + PP_Instance instance, + PP_ResourceString string_id) { + DebugPrintf("PPB_PDF::GetLocalizedString: " + "instance=%"NACL_PRIu32"\n", instance); + + NaClSrpcChannel* channel = GetMainSrpcChannel(); + nacl_abi_size_t string_size = kMaxVarSize; + nacl::scoped_array<char> string_bytes(new char[kMaxVarSize]); + NaClSrpcError srpc_result = + PpbPdfRpcClient::PPB_PDF_GetLocalizedString( + channel, + instance, + static_cast<int32_t>(string_id), + &string_size, string_bytes.get()); + + PP_Var string = PP_MakeUndefined(); + if (srpc_result == NACL_SRPC_RESULT_OK) { + (void) DeserializeTo( + channel, string_bytes.get(), string_size, 1, &string); + } + + DebugPrintf("PPB_PDF::GetLocalizedString: %s\n", + NaClSrpcErrorString(srpc_result)); + return string; +} + +PP_Resource GetResourceImage(PP_Instance instance, + PP_ResourceImage image_id) { + DebugPrintf("PPB_PDF::GetResourceImage: " + "instance=%"NACL_PRIu32"\n", instance); + + PP_Resource image = kInvalidResourceId; + NaClSrpcError srpc_result = + PpbPdfRpcClient::PPB_PDF_GetResourceImage( + GetMainSrpcChannel(), + instance, + static_cast<int32_t>(image_id), + &image); + + DebugPrintf("PPB_PDF::GetResourceImage: %s\n", + NaClSrpcErrorString(srpc_result)); + if (srpc_result == NACL_SRPC_RESULT_OK) { + scoped_refptr<PluginImageData> image_data = + PluginResource::AdoptAs<PluginImageData>(image); + if (image_data.get()) { + return image; + } + } + return kInvalidResourceId; +} + +PP_Resource GetFontFileWithFallback( + PP_Instance instance, + const struct PP_FontDescription_Dev* description, + PP_PrivateFontCharset charset) { + DebugPrintf("PPB_PDF::GetFontFileWithFallback: Not Implemented\n"); + return kInvalidResourceId; +} + +bool GetFontTableForPrivateFontFile(PP_Resource font_file, + uint32_t table, + void* output, + uint32_t* output_length) { + DebugPrintf("PPB_PDF::GetFontTableForPrivateFontFile: Not Implemented\n"); + *output_length = 0; + return false; +} + +nacl_abi_size_t utf16_length(const unsigned short* str) { + const unsigned short* s = str; + while (*s) + ++s; + return (s - str); +} + +void SearchString(PP_Instance instance, + const unsigned short* string, + const unsigned short* term, + bool case_sensitive, + struct PP_PrivateFindResult** results, + int* count) { + DebugPrintf("PPB_PDF::SearchString: instance=%"NACL_PRIu32"\n", instance); + + CHECK(string != NULL); + CHECK(term != NULL); + CHECK(results != NULL); + CHECK(count != NULL); + + nacl_abi_size_t find_results_size = kMaxFindResultsBytes; + *results = reinterpret_cast<PP_PrivateFindResult*>(malloc(find_results_size)); + *count = 0; + + nacl_abi_size_t string_length = utf16_length(string); + nacl_abi_size_t term_length = utf16_length(term); + if (string_length > 0 && term_length > 0) { + NaClSrpcError srpc_result = + PpbPdfRpcClient::PPB_PDF_SearchString( + GetMainSrpcChannel(), + instance, + (string_length + 1) * sizeof(unsigned short), // include NULL + reinterpret_cast<char*>(const_cast<unsigned short*>(string)), + (term_length + 1) * sizeof(unsigned short), // include NULL + reinterpret_cast<char*>(const_cast<unsigned short*>(term)), + static_cast<int32_t>(case_sensitive), + &find_results_size, + reinterpret_cast<char*>(*results), + reinterpret_cast<int32_t*>(count)); + + DebugPrintf("PPB_PDF::SearchString: %s\n", + NaClSrpcErrorString(srpc_result)); + } +} + +void DidStartLoading(PP_Instance instance) { + DebugPrintf("PPB_PDF::DidStartLoading: instance=%"NACL_PRIu32"\n", + instance); + + NaClSrpcError srpc_result = + PpbPdfRpcClient::PPB_PDF_DidStartLoading(GetMainSrpcChannel(), + instance); + + DebugPrintf("PPB_PDF::DidStartLoading: %s\n", + NaClSrpcErrorString(srpc_result)); +} + +void DidStopLoading(PP_Instance instance) { + DebugPrintf("PPB_PDF::DidStopLoading: instance=%"NACL_PRIu32"\n", + instance); + + NaClSrpcError srpc_result = + PpbPdfRpcClient::PPB_PDF_DidStopLoading(GetMainSrpcChannel(), + instance); + + DebugPrintf("PPB_PDF::DidStopLoading: %s\n", + NaClSrpcErrorString(srpc_result)); +} + +void SetContentRestriction(PP_Instance instance, + int restrictions) { + DebugPrintf("PPB_PDF::SetContentRestriction: instance=%"NACL_PRIu32"\n", + instance); + + NaClSrpcError srpc_result = + PpbPdfRpcClient::PPB_PDF_SetContentRestriction(GetMainSrpcChannel(), + instance, + restrictions); + + DebugPrintf("PPB_PDF::SetContentRestriction: %s\n", + NaClSrpcErrorString(srpc_result)); +} + +void HistogramPDFPageCount(int count) { + DebugPrintf("PPB_PDF::HistogramPDFPageCount/n"); + + NaClSrpcError srpc_result = + PpbPdfRpcClient::PPB_PDF_HistogramPDFPageCount(GetMainSrpcChannel(), + count); + + DebugPrintf("PPB_PDF::HistogramPDFPageCount: %s\n", + NaClSrpcErrorString(srpc_result)); +} + +void UserMetricsRecordAction(struct PP_Var action) { + DebugPrintf("PPB_PDF::UserMetricsRecordAction\n"); + + nacl_abi_size_t action_size = kMaxVarSize; + nacl::scoped_array<char> action_bytes( + Serialize(&action, 1, &action_size)); + NaClSrpcError srpc_result = + PpbPdfRpcClient::PPB_PDF_UserMetricsRecordAction(GetMainSrpcChannel(), + action_size, + action_bytes.get()); + + DebugPrintf("PPB_PDF::UserMetricsRecordAction: %s\n", + NaClSrpcErrorString(srpc_result)); +} + +void HasUnsupportedFeature(PP_Instance instance) { + DebugPrintf("PPB_PDF::HasUnsupportedFeature: instance=%"NACL_PRIu32"\n", + instance); + + NaClSrpcError srpc_result = + PpbPdfRpcClient::PPB_PDF_HasUnsupportedFeature(GetMainSrpcChannel(), + instance); + + DebugPrintf("PPB_PDF::HasUnsupportedFeature: %s\n", + NaClSrpcErrorString(srpc_result)); +} + +void SaveAs(PP_Instance instance) { + DebugPrintf("PPB_PDF::SaveAs: instance=%"NACL_PRIu32"\n", instance); + + NaClSrpcError srpc_result = + PpbPdfRpcClient::PPB_PDF_SaveAs(GetMainSrpcChannel(), + instance); + + DebugPrintf("PPB_PDF::SaveAs: %s\n", NaClSrpcErrorString(srpc_result)); +} + +} // namespace + +const PPB_PDF* PluginPDF::GetInterface() { + static const PPB_PDF pdf_interface = { + GetLocalizedString, + GetResourceImage, + GetFontFileWithFallback, + GetFontTableForPrivateFontFile, + SearchString, + DidStartLoading, + DidStopLoading, + SetContentRestriction, + HistogramPDFPageCount, + UserMetricsRecordAction, + HasUnsupportedFeature, + SaveAs + }; + return &pdf_interface; +} + +} // namespace ppapi_proxy + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_pdf.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_pdf.h new file mode 100644 index 0000000..ca3a7fc --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_pdf.h @@ -0,0 +1,26 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_PDF_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_PDF_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "ppapi/c/private/ppb_pdf.h" + +namespace ppapi_proxy { + +// Implements the untrusted side of the PPB_PDF private interface. +class PluginPDF { + public: + PluginPDF(); + static const PPB_PDF* GetInterface(); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(PluginPDF); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_PDF_H_ + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_scrollbar.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_scrollbar.cc new file mode 100644 index 0000000..4e0b38d --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_scrollbar.cc @@ -0,0 +1,201 @@ +// 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/plugin_ppb_scrollbar.h" + +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/plugin_callback.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/dev/ppb_scrollbar_dev.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_rect.h" +#include "srpcgen/ppb_rpc.h" + +namespace ppapi_proxy { + +namespace { + +const nacl_abi_size_t kPPRectBytes = + static_cast<nacl_abi_size_t>(sizeof(struct PP_Rect)); + +PP_Resource Create(PP_Instance instance, PP_Bool vertical) { + DebugPrintf("PPB_Scrollbar::Create: " + "instance=%"NACL_PRIu32"\n", + instance); + + PP_Resource scrollbar = kInvalidResourceId; + NaClSrpcError srpc_result = + PpbScrollbarRpcClient::PPB_Scrollbar_Create( + GetMainSrpcChannel(), + instance, + vertical, + &scrollbar); + + DebugPrintf("PPB_Scrollbar::Create: %s\n", + NaClSrpcErrorString(srpc_result)); + return scrollbar; +} + +PP_Bool IsScrollbar(PP_Resource resource) { + DebugPrintf("PPB_Scrollbar::IsScrollbar: " + "resource=%"NACL_PRIu32"\n", + resource); + + int32_t is_scrollbar = 0; + NaClSrpcError srpc_result = + PpbScrollbarRpcClient::PPB_Scrollbar_IsScrollbar( + GetMainSrpcChannel(), + resource, + &is_scrollbar); + + DebugPrintf("PPB_Scrollbar::IsScrollbar: %s\n", + NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK && is_scrollbar) + return PP_TRUE; + return PP_FALSE; +} + +uint32_t GetThickness(PP_Resource resource) { + DebugPrintf("PPB_Scrollbar::GetThickness"); + + int32_t thickness = 0; + NaClSrpcError srpc_result = + PpbScrollbarRpcClient::PPB_Scrollbar_GetThickness( + GetMainSrpcChannel(), + resource, + &thickness); + + DebugPrintf("PPB_Scrollbar::GetThickness: %s\n", + NaClSrpcErrorString(srpc_result)); + + return thickness; +} + +PP_Bool IsOverlay(PP_Resource resource) { + DebugPrintf("PPB_Scrollbar::IsOverlay: " + "resource=%"NACL_PRIu32"\n", + resource); + + int32_t is_overlay = 0; + NaClSrpcError srpc_result = + PpbScrollbarRpcClient::PPB_Scrollbar_IsOverlay( + GetMainSrpcChannel(), + resource, + &is_overlay); + + DebugPrintf("PPB_Scrollbar::IsOverlay: %s\n", + NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK && is_overlay) + return PP_TRUE; + return PP_FALSE; +} + +uint32_t GetValue(PP_Resource scrollbar) { + DebugPrintf("PPB_Scrollbar::GetValue: " + "scrollbar=%"NACL_PRIu32"\n", + scrollbar); + + int32_t value = 0; + NaClSrpcError srpc_result = + PpbScrollbarRpcClient::PPB_Scrollbar_GetValue( + GetMainSrpcChannel(), + scrollbar, + &value); + + DebugPrintf("PPB_Scrollbar::GetValue: %s\n", + NaClSrpcErrorString(srpc_result)); + + return value; +} + +void SetValue(PP_Resource scrollbar, uint32_t value) { + DebugPrintf("PPB_Scrollbar::SetValue: " + "scrollbar=%"NACL_PRIu32"\n", + scrollbar); + + NaClSrpcError srpc_result = + PpbScrollbarRpcClient::PPB_Scrollbar_SetValue( + GetMainSrpcChannel(), + scrollbar, + value); + + DebugPrintf("PPB_Scrollbar::SetValue: %s\n", + NaClSrpcErrorString(srpc_result)); +} + +void SetDocumentSize(PP_Resource scrollbar, uint32_t size) { + DebugPrintf("PPB_Scrollbar::SetDocumentSize: " + "scrollbar=%"NACL_PRIu32"\n", scrollbar); + + NaClSrpcError srpc_result = + PpbScrollbarRpcClient::PPB_Scrollbar_SetDocumentSize( + GetMainSrpcChannel(), + scrollbar, + size); + + DebugPrintf("PPB_Scrollbar::SetDocumentSize: %s\n", + NaClSrpcErrorString(srpc_result)); +} + +void SetTickMarks(PP_Resource scrollbar, + const struct PP_Rect* tick_marks, + uint32_t count) { + DebugPrintf("PPB_Scrollbar::SetTickMarks: " + "scrollbar=%"NACL_PRIu32"\n", + scrollbar); + + nacl_abi_size_t tick_marks_bytes = kPPRectBytes * count; + NaClSrpcError srpc_result = + PpbScrollbarRpcClient::PPB_Scrollbar_SetTickMarks( + GetMainSrpcChannel(), + scrollbar, + tick_marks_bytes, + reinterpret_cast<char*>(const_cast<struct PP_Rect*>(tick_marks)), + count); + + DebugPrintf("PPB_Scrollbar::SetTickMarks: %s\n", + NaClSrpcErrorString(srpc_result)); +} + +void ScrollBy(PP_Resource scrollbar, + PP_ScrollBy_Dev unit, + int32_t multiplier) { + DebugPrintf("PPB_Scrollbar::ScrollBy: " + "scrollbar=%"NACL_PRIu32"\n", + scrollbar); + + NaClSrpcError srpc_result = + PpbScrollbarRpcClient::PPB_Scrollbar_ScrollBy( + GetMainSrpcChannel(), + scrollbar, + unit, + multiplier); + + DebugPrintf("PPB_Scrollbar::ScrollBy: %s\n", + NaClSrpcErrorString(srpc_result)); +} + +} // namespace + +const PPB_Scrollbar_Dev* PluginScrollbar::GetInterface() { + static const PPB_Scrollbar_Dev scrollbar_interface = { + Create, + IsScrollbar, + GetThickness, + IsOverlay, + GetValue, + SetValue, + SetDocumentSize, + SetTickMarks, + ScrollBy + }; + return &scrollbar_interface; +} + +} // namespace ppapi_proxy + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_scrollbar.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_scrollbar.h new file mode 100644 index 0000000..0a48c00 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_scrollbar.h @@ -0,0 +1,26 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_SCROLLBAR_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_SCROLLBAR_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "ppapi/c/dev/ppb_scrollbar_dev.h" + +namespace ppapi_proxy { + +// Implements the untrusted side of the PPB_Scrollbar_Dev interface. +class PluginScrollbar { + public: + PluginScrollbar(); + static const PPB_Scrollbar_Dev* GetInterface(); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(PluginScrollbar); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_SCROLLBAR_H_ + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_testing.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_testing.cc new file mode 100644 index 0000000..b993b26 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_testing.cc @@ -0,0 +1,104 @@ +// 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/plugin_ppb_testing.h" + +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/object_serialize.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/plugin_callback.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/dev/ppb_testing_dev.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_point.h" +#include "ppapi/c/pp_rect.h" +#include "srpcgen/ppb_rpc.h" + +namespace ppapi_proxy { + +namespace { + +const nacl_abi_size_t kPPPointBytes = + static_cast<nacl_abi_size_t>(sizeof(struct PP_Point)); + +PP_Bool ReadImageData(PP_Resource device_context_2d, + PP_Resource image, + const struct PP_Point* top_left) { + DebugPrintf("PPB_Testing::ReadImageData: device_context_2d=%"NACL_PRIu32"\n", + device_context_2d); + + int32_t success = 0; + NaClSrpcError srpc_result = + PpbTestingRpcClient::PPB_Testing_ReadImageData( + GetMainSrpcChannel(), + device_context_2d, + image, + kPPPointBytes, + reinterpret_cast<char*>(const_cast<PP_Point*>(top_left)), + &success); + + DebugPrintf("PPB_Testing::ReadImageData: %s\n", + NaClSrpcErrorString(srpc_result)); + if (srpc_result == NACL_SRPC_RESULT_OK && success) + return PP_TRUE; + return PP_FALSE; +} + +void RunMessageLoop(PP_Instance instance) { + DebugPrintf("PPB_Testing::RunMessageLoop: instance=%"NACL_PRIu32"\n", + instance); + + NaClSrpcError srpc_result = + PpbTestingRpcClient::PPB_Testing_RunMessageLoop( + GetMainSrpcChannel(), + instance); + + DebugPrintf("PPB_Testing::RunMessageLoop: %s\n", + NaClSrpcErrorString(srpc_result)); +} + +void QuitMessageLoop(PP_Instance instance) { + DebugPrintf("PPB_Testing::QuitMessageLoop: instance=%"NACL_PRIu32"\n", + instance); + + NaClSrpcError srpc_result = + PpbTestingRpcClient::PPB_Testing_QuitMessageLoop( + GetMainSrpcChannel(), + instance); + + DebugPrintf("PPB_Testing::QuitMessageLoop: %s\n", + NaClSrpcErrorString(srpc_result)); +} + +uint32_t GetLiveObjectsForInstance(PP_Instance instance) { + DebugPrintf("PPB_Testing::GetLiveObjectsForInstance: " + "instance=%"NACL_PRIu32"\n", instance); + + int32_t live_object_count = 0; + NaClSrpcError srpc_result = + PpbTestingRpcClient::PPB_Testing_GetLiveObjectsForInstance( + GetMainSrpcChannel(), + instance, + &live_object_count); + + DebugPrintf("PPB_Testing::GetLiveObjectsForInstance: %s\n", + NaClSrpcErrorString(srpc_result)); + return live_object_count; +} + +} // namespace + +const PPB_Testing_Dev* PluginTesting::GetInterface() { + static const PPB_Testing_Dev testing_interface = { + ReadImageData, + RunMessageLoop, + QuitMessageLoop, + GetLiveObjectsForInstance + }; + return &testing_interface; +} + +} // namespace ppapi_proxy diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_testing.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_testing.h new file mode 100644 index 0000000..b1930badb --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_testing.h @@ -0,0 +1,26 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_TESTING_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_TESTING_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "ppapi/c/dev/ppb_testing_dev.h" + +namespace ppapi_proxy { + +// Implements the untrusted side of the PPB_Testing_Dev interface. +class PluginTesting { + public: + PluginTesting(); + static const PPB_Testing_Dev* GetInterface(); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(PluginTesting); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_TESTING_H_ + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_url_loader.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_url_loader.cc new file mode 100644 index 0000000..569186e --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_url_loader.cc @@ -0,0 +1,237 @@ +// 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/plugin_ppb_url_loader.h" + +#include <stdio.h> +#include <string.h> +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/plugin_callback.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/ppb_url_loader.h" +#include "srpcgen/ppb_rpc.h" + +namespace ppapi_proxy { + +namespace { + +PP_Resource Create(PP_Instance instance) { + DebugPrintf("PPB_URLLoader::Create: instance=%"NACL_PRIu32"\n", instance); + + PP_Resource resource; + NaClSrpcError srpc_result = + PpbURLLoaderRpcClient::PPB_URLLoader_Create( + GetMainSrpcChannel(), instance, &resource); + DebugPrintf("PPB_URLLoader::Create: %s\n", NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK) + return resource; + return kInvalidResourceId; +} + +PP_Bool IsURLLoader(PP_Resource resource) { + DebugPrintf("PPB_URLLoader::IsURLLoader: resource=%"NACL_PRIu32"\n", + resource); + + int32_t is_url_loader; + NaClSrpcError srpc_result = + PpbURLLoaderRpcClient::PPB_URLLoader_IsURLLoader( + GetMainSrpcChannel(), resource, &is_url_loader); + DebugPrintf("PPB_URLLoader::IsURLLoader: %s\n", + NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK && is_url_loader) + return PP_TRUE; + return PP_FALSE; +} + +int32_t Open(PP_Resource loader, + PP_Resource request, + struct PP_CompletionCallback callback) { + DebugPrintf("PPB_URLLoader::Open: loader=%"NACL_PRIu32"\n", loader); + DebugPrintf("PPB_URLLoader::Open: request=%"NACL_PRIu32"\n", request); + + int32_t callback_id = + CompletionCallbackTable::Get()->AddCallback(callback); + if (callback_id == 0) // Just like Chrome, for now disallow blocking calls. + return PP_ERROR_BADARGUMENT; + + int32_t pp_error; + NaClSrpcError srpc_result = + PpbURLLoaderRpcClient::PPB_URLLoader_Open( + GetMainSrpcChannel(), loader, request, callback_id, &pp_error); + DebugPrintf("PPB_URLLoader::Open: %s\n", NaClSrpcErrorString(srpc_result)); + + if (srpc_result != NACL_SRPC_RESULT_OK) + pp_error = PP_ERROR_FAILED; + return MayForceCallback(callback, pp_error); +} + +int32_t FollowRedirect(PP_Resource loader, + struct PP_CompletionCallback callback) { + DebugPrintf("PPB_URLLoader::FollowRedirect: loader=%"NACL_PRIu32"\n", loader); + + int32_t callback_id = + CompletionCallbackTable::Get()->AddCallback(callback); + if (callback_id == 0) // Just like Chrome, for now disallow blocking calls. + return PP_ERROR_BADARGUMENT; + + int32_t pp_error; + NaClSrpcError srpc_result = + PpbURLLoaderRpcClient::PPB_URLLoader_FollowRedirect( + GetMainSrpcChannel(), loader, callback_id, &pp_error); + DebugPrintf("PPB_URLLoader::FollowRedirect: %s\n", + NaClSrpcErrorString(srpc_result)); + + if (srpc_result != NACL_SRPC_RESULT_OK) + pp_error = PP_ERROR_FAILED; + return MayForceCallback(callback, pp_error); +} + +PP_Bool GetUploadProgress(PP_Resource loader, + int64_t* bytes_sent, + int64_t* total_bytes_to_be_sent) { + DebugPrintf("PPB_URLLoader::GetUploadProgress: loader=%"NACL_PRIu32"\n", + loader); + + int32_t success; + NaClSrpcError srpc_result = + PpbURLLoaderRpcClient::PPB_URLLoader_GetUploadProgress( + GetMainSrpcChannel(), + loader, + bytes_sent, + total_bytes_to_be_sent, + &success); + DebugPrintf("PPB_URLLoader::GetUploadProgress: %s\n", + NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK && success) + return PP_TRUE; + return PP_FALSE; +} + +PP_Bool GetDownloadProgress(PP_Resource loader, + int64_t* bytes_received, + int64_t* total_bytes_to_be_received) { + DebugPrintf("PPB_URLLoader::GetDownloadProgress: loader=%"NACL_PRIu32"\n", + loader); + + int32_t success; + NaClSrpcError srpc_result = + PpbURLLoaderRpcClient::PPB_URLLoader_GetDownloadProgress( + GetMainSrpcChannel(), + loader, + bytes_received, + total_bytes_to_be_received, + &success); + DebugPrintf("PPB_URLLoader::GetDownloadProgress: %s\n", + NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK && success) + return PP_TRUE; + return PP_FALSE; +} + +PP_Resource GetResponseInfo(PP_Resource loader) { + DebugPrintf("PPB_URLLoader::GetResponseInfo: loader=%"NACL_PRIu32"\n", + loader); + + PP_Resource response; + NaClSrpcError srpc_result = + PpbURLLoaderRpcClient::PPB_URLLoader_GetResponseInfo( + GetMainSrpcChannel(), + loader, + &response); + + if (srpc_result == NACL_SRPC_RESULT_OK) + return response; + return kInvalidResourceId; +} + +int32_t ReadResponseBody(PP_Resource loader, + void* buffer, + int32_t bytes_to_read, + struct PP_CompletionCallback callback) { + DebugPrintf("PPB_URLLoader::ReadResponseBody: loader=%"NACL_PRIu32"\n", + loader); + if (bytes_to_read < 0) + bytes_to_read = 0; + nacl_abi_size_t buffer_size = bytes_to_read; + + int32_t callback_id = + CompletionCallbackTable::Get()->AddCallback(callback, buffer); + if (callback_id == 0) // Just like Chrome, for now disallow blocking calls. + return PP_ERROR_BADARGUMENT; + + int32_t pp_error_or_bytes; + NaClSrpcError srpc_result = + PpbURLLoaderRpcClient::PPB_URLLoader_ReadResponseBody( + GetMainSrpcChannel(), + loader, + bytes_to_read, + callback_id, + &buffer_size, + static_cast<char*>(buffer), + &pp_error_or_bytes); + DebugPrintf("PPB_URLLoader::ReadResponseBody: %s\n", + NaClSrpcErrorString(srpc_result)); + + if (srpc_result != NACL_SRPC_RESULT_OK) + pp_error_or_bytes = PP_ERROR_FAILED; + return MayForceCallback(callback, pp_error_or_bytes); +} + +int32_t FinishStreamingToFile(PP_Resource loader, + struct PP_CompletionCallback callback) { + DebugPrintf("PPB_URLLoader::FinishStreamingToFile: loader=%"NACL_PRIu32"\n", + loader); + + int32_t callback_id = + CompletionCallbackTable::Get()->AddCallback(callback); + if (callback_id == 0) // Just like Chrome, for now disallow blocking calls. + return PP_ERROR_BADARGUMENT; + + int32_t pp_error; + NaClSrpcError srpc_result = + PpbURLLoaderRpcClient::PPB_URLLoader_FinishStreamingToFile( + GetMainSrpcChannel(), loader, callback_id, &pp_error); + + if (srpc_result != NACL_SRPC_RESULT_OK) + pp_error = PP_ERROR_FAILED; + return MayForceCallback(callback, pp_error); +} + +void Close(PP_Resource loader) { + DebugPrintf("PPB_URLLoader::Close: loader=%"NACL_PRIu32"\n", loader); + + NaClSrpcError srpc_result = + PpbURLLoaderRpcClient::PPB_URLLoader_Close( + GetMainSrpcChannel(), loader); + DebugPrintf("PPB_URLLoader::Close: %s\n", NaClSrpcErrorString(srpc_result)); +} + +} // namespace + +const PPB_URLLoader* PluginURLLoader::GetInterface() { + static const PPB_URLLoader url_loader_interface = { + Create, + IsURLLoader, + Open, + FollowRedirect, + GetUploadProgress, + GetDownloadProgress, + GetResponseInfo, + ReadResponseBody, + FinishStreamingToFile, + Close, + }; + return &url_loader_interface; +} + +} // namespace ppapi_proxy diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_url_loader.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_url_loader.h new file mode 100644 index 0000000..81b2e83 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_url_loader.h @@ -0,0 +1,24 @@ +// Copyright 2010 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_URL_LOADER_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_URL_LOADER_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "ppapi/c/ppb_url_loader.h" + +namespace ppapi_proxy { + +// Implements the untrusted side of the PPB_URLLoader interface. +class PluginURLLoader { + public: + static const PPB_URLLoader* GetInterface(); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(PluginURLLoader); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_URL_LOADER_H_ diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_url_request_info.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_url_request_info.cc new file mode 100644 index 0000000..ab75b6c --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_url_request_info.cc @@ -0,0 +1,140 @@ +// Copyright 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/plugin_ppb_url_request_info.h" + +#include <stdio.h> +#include <string.h> +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/object_serialize.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "ppapi/c/ppb_url_request_info.h" +#include "srpcgen/ppb_rpc.h" + +namespace ppapi_proxy { + +namespace { + +PP_Resource Create(PP_Instance instance) { + DebugPrintf("PPB_URLRequestInfo::Create: instance=%"NACL_PRIu32"\n", + instance); + + PP_Resource resource; + NaClSrpcError srpc_result = + PpbURLRequestInfoRpcClient::PPB_URLRequestInfo_Create( + GetMainSrpcChannel(), instance, &resource); + DebugPrintf("PPB_URLRequestInfo::Create: %s\n", + NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK) + return resource; + return kInvalidResourceId; +} + +PP_Bool IsURLRequestInfo(PP_Resource resource) { + DebugPrintf("PPB_URLRequestInfo::IsURLRequestInfo: resource=%"NACL_PRIu32"\n", + resource); + + int32_t success; + NaClSrpcError srpc_result = + PpbURLRequestInfoRpcClient::PPB_URLRequestInfo_IsURLRequestInfo( + GetMainSrpcChannel(), resource, &success); + DebugPrintf("PPB_URLRequestInfo::IsURLRequestInfo: %s\n", + NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK && success) + return PP_TRUE; + return PP_FALSE; +} + +PP_Bool SetProperty(PP_Resource request, + PP_URLRequestProperty property, + struct PP_Var value) { + DebugPrintf("PPB_URLRequestInfo::SetProperty: request=%"NACL_PRIu32"\n", + request); + + nacl_abi_size_t value_size = kMaxVarSize; + nacl::scoped_array<char> value_bytes(Serialize(&value, 1, &value_size)); + + int32_t success; + NaClSrpcError srpc_result = + PpbURLRequestInfoRpcClient::PPB_URLRequestInfo_SetProperty( + GetMainSrpcChannel(), + request, + static_cast<int32_t>(property), + value_size, + value_bytes.get(), + &success); + DebugPrintf("PPB_URLRequestInfo::SetProperty: %s\n", + NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK && success) + return PP_TRUE; + return PP_FALSE; +} + +PP_Bool AppendDataToBody(PP_Resource request, const void* data, uint32_t len) { + DebugPrintf("PPB_URLRequestInfo::AppendDataToBody: request=%"NACL_PRIu32"\n", + request); + + int32_t success; + NaClSrpcError srpc_result = + PpbURLRequestInfoRpcClient::PPB_URLRequestInfo_AppendDataToBody( + GetMainSrpcChannel(), + request, + static_cast<nacl_abi_size_t>(len), + static_cast<char*>(const_cast<void*>(data)), + &success); + DebugPrintf("PPB_URLRequestInfo::AppendDataToBody: %s\n", + NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK && success) + return PP_TRUE; + return PP_FALSE; +} + +PP_Bool AppendFileToBody(PP_Resource request, + PP_Resource file_ref, + int64_t start_offset, + int64_t number_of_bytes, + PP_Time expected_last_modified_time) { + DebugPrintf("PPB_URLRequestInfo::AppendFileToBody: request=%"NACL_PRIu32"\n", + request); + + int32_t success; + NaClSrpcError srpc_result = + PpbURLRequestInfoRpcClient::PPB_URLRequestInfo_AppendFileToBody( + GetMainSrpcChannel(), + request, + file_ref, + start_offset, + number_of_bytes, + static_cast<double>(expected_last_modified_time), + &success); + DebugPrintf("PPB_URLRequestInfo::AppendFileToBody: %s\n", + NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK && success) + return PP_TRUE; + return PP_FALSE; +} + +} // namespace + +const PPB_URLRequestInfo* PluginURLRequestInfo::GetInterface() { + static const PPB_URLRequestInfo url_request_info_interface = { + Create, + IsURLRequestInfo, + SetProperty, + AppendDataToBody, + AppendFileToBody, + }; + return &url_request_info_interface; +} + +} // namespace ppapi_proxy diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_url_request_info.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_url_request_info.h new file mode 100644 index 0000000..97f465c --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_url_request_info.h @@ -0,0 +1,24 @@ +// Copyright 2010 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_URL_REQUEST_INFO_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_URL_REQUEST_INFO_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "ppapi/c/ppb_url_request_info.h" + +namespace ppapi_proxy { + +// Implements the untrusted side of the PPB_URLRequestInfo interface. +class PluginURLRequestInfo { + public: + static const PPB_URLRequestInfo* GetInterface(); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(PluginURLRequestInfo); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_URL_REQUEST_INFO_H_ diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_url_response_info.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_url_response_info.cc new file mode 100644 index 0000000..3d78b48 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_url_response_info.cc @@ -0,0 +1,90 @@ +// Copyright 2010 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/plugin_ppb_url_response_info.h" + +#include <stdio.h> +#include <string.h> +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/object_serialize.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "ppapi/c/ppb_url_response_info.h" +#include "srpcgen/ppb_rpc.h" + +namespace ppapi_proxy { + +namespace { + +PP_Bool IsURLResponseInfo(PP_Resource resource) { + DebugPrintf("PPB_URLResponseInfo::IsURLResponseInfo: resource=%"NACL_PRIu32 + "\n", resource); + + int32_t success; + NaClSrpcError srpc_result = + PpbURLResponseInfoRpcClient::PPB_URLResponseInfo_IsURLResponseInfo( + GetMainSrpcChannel(), resource, &success); + DebugPrintf("PPB_URLResponseInfo::IsURLResponseInfo: %s\n", + NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK && success) + return PP_TRUE; + return PP_FALSE; +} + +PP_Var GetProperty(PP_Resource response, PP_URLResponseProperty property) { + DebugPrintf("PPB_URLResponseInfo::GetProperty: response=%"NACL_PRIu32"\n", + response); + NaClSrpcChannel* channel = GetMainSrpcChannel(); + + PP_Var value = PP_MakeUndefined(); + nacl_abi_size_t value_size = kMaxVarSize; + nacl::scoped_array<char> value_bytes(new char[kMaxVarSize]); + + NaClSrpcError srpc_result = + PpbURLResponseInfoRpcClient::PPB_URLResponseInfo_GetProperty( + channel, + response, + static_cast<int32_t>(property), + &value_size, + value_bytes.get()); + DebugPrintf("PPB_URLResponseInfo::GetProperty: %s\n", + NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK) + (void) DeserializeTo(channel, value_bytes.get(), value_size, 1, &value); + return value; +} + +PP_Resource GetBodyAsFileRef(PP_Resource response) { + DebugPrintf("PPB_URLResponseInfo::GetBodyAsFileRef: response=%"NACL_PRIu32 + "\n", response); + + PP_Resource file_ref; + NaClSrpcError srpc_result = + PpbURLResponseInfoRpcClient::PPB_URLResponseInfo_GetBodyAsFileRef( + GetMainSrpcChannel(), response, &file_ref); + DebugPrintf("PPB_URLResponseInfo::GetBodyAsFileRef: %s\n", + NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK) + return file_ref; + return kInvalidResourceId; +} + +} // namespace + +const PPB_URLResponseInfo* PluginURLResponseInfo::GetInterface() { + static const PPB_URLResponseInfo url_response_info_interface = { + IsURLResponseInfo, + GetProperty, + GetBodyAsFileRef, + }; + return &url_response_info_interface; +} + +} // namespace ppapi_proxy diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_url_response_info.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_url_response_info.h new file mode 100644 index 0000000..7209b2f --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_url_response_info.h @@ -0,0 +1,24 @@ +// Copyright 2010 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_URL_RESPONSE_INFO_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_URL_RESPONSE_INFO_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "ppapi/c/ppb_url_response_info.h" + +namespace ppapi_proxy { + +// Implements the untrusted side of the PPB_URLResponseInfo interface. +class PluginURLResponseInfo { + public: + static const PPB_URLResponseInfo* GetInterface(); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(PluginURLResponseInfo); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_URL_RESPONSE_INFO_H_ diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_var.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_var.cc new file mode 100644 index 0000000..48f6aa1 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_var.cc @@ -0,0 +1,199 @@ +// 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/plugin_ppb_var.h" + +#include <stdio.h> + +#include <string> +#include <utility> + +#include "native_client/src/include/checked_cast.h" +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/include/portability_io.h" +#include "native_client/src/shared/ppapi_proxy/proxy_var_cache.h" +#include "native_client/src/shared/ppapi_proxy/string_proxy_var.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/pp_var.h" +#include "ppapi/c/ppb_var.h" + +namespace ppapi_proxy { + +namespace { + +void AddRef(PP_Var var) { + DebugPrintf("PPB_Var::AddRef: var=PPB_Var(%s)\n", + PluginVar::DebugString(var).c_str()); + ProxyVarCache::GetInstance().RetainProxyVar(var); +} + +void Release(PP_Var var) { + DebugPrintf("PPB_Var::Release: var=PPB_Var(%s)\n", + PluginVar::DebugString(var).c_str()); + ProxyVarCache::GetInstance().ReleaseProxyVar(var); +} + +PP_Var VarFromUtf8(PP_Module module_id, const char* data, uint32_t len) { + DebugPrintf("PPB_Var::VarFromUtf8: data='%.*s'\n", len, data); + UNREFERENCED_PARAMETER(module_id); + if (!StringIsUtf8(data, len)) { + DebugPrintf("PPB_Var::VarFromUtf8: not UTF8\n"); + return PP_MakeNull(); + } + SharedProxyVar proxy_var(new StringProxyVar(data, len)); + ProxyVarCache::GetInstance().RetainSharedProxyVar(proxy_var); + PP_Var var; + var.type = PP_VARTYPE_STRING; + var.value.as_id = proxy_var->id(); + // Increment the reference count for the return to the caller. + AddRef(var); + DebugPrintf("PPB_Var::VarFromUtf8: as_id=%"NACL_PRId64"\n", var.value.as_id); + return var; +} + +const char* VarToUtf8(PP_Var var, uint32_t* len) { + DebugPrintf("PPB_Var::VarToUtf8: as_id=%"NACL_PRId64"\n", var.value.as_id); + SharedStringProxyVar string_var = StringProxyVar::CastFromProxyVar( + ProxyVarCache::GetInstance().SharedProxyVarForVar(var)); + const char* data = NULL; + if (string_var == NULL) { + *len = 0; + } else { + *len = static_cast<uint32_t>(string_var->contents().size()); + // Mimics PPAPI implementation: as long as SharedStringProxyVar is alive, + // the return value can be validly used. + data = string_var->contents().c_str(); + } + DebugPrintf("PPB_Var::VarToUtf8: data='%.*s'\n", *len, data); + return data; +} + +int64_t GetVarId(PP_Var var) { + SharedProxyVar proxy_var = + ProxyVarCache::GetInstance().SharedProxyVarForVar(var); + if (proxy_var == NULL) { + return -1; + } else { + return proxy_var->id(); + } +} + +} // namespace + +const PPB_Var* PluginVar::GetInterface() { + static const PPB_Var var_interface = { + AddRef, + Release, + VarFromUtf8, + VarToUtf8 + }; + return &var_interface; +} + +std::string PluginVar::DebugString(const PP_Var& var) { + switch (var.type) { + case PP_VARTYPE_UNDEFINED: + return "##UNDEFINED##"; + case PP_VARTYPE_NULL: + return "##NULL##"; + case PP_VARTYPE_BOOL: + return (var.value.as_bool ? "true" : "false"); + case PP_VARTYPE_INT32: + { + char buf[32]; + const size_t kBufSize = sizeof(buf); + SNPRINTF(buf, kBufSize, "%d", static_cast<int>(var.value.as_int)); + return buf; + } + case PP_VARTYPE_DOUBLE: + { + char buf[32]; + const size_t kBufSize = sizeof(buf); + SNPRINTF(buf, kBufSize, "%f", var.value.as_double); + return buf; + } + case PP_VARTYPE_STRING: + { + uint32_t len; + const char* data = VarToUtf8(var, &len); + return std::string(data, len); + } + case PP_VARTYPE_OBJECT: + { + char buf[32]; + const size_t kBufSize = sizeof(buf); + SNPRINTF(buf, kBufSize, "%"NACL_PRIu64"", GetVarId(var)); + return std::string("##OBJECT##") + buf + "##"; + } + case PP_VARTYPE_ARRAY: + case PP_VARTYPE_DICTIONARY: + NACL_NOTREACHED(); + break; + } + ASSERT_MSG(0, "Unexpected type seen"); + return "##ERROR##"; +} + +PP_Var PluginVar::StringToPPVar(PP_Module module_id, const std::string& str) { + static const PPB_Var* ppb_var = NULL; + if (ppb_var == NULL) { + ppb_var = static_cast<const PPB_Var*>( + ppapi_proxy::PluginVar::GetInterface()); + } + if (ppb_var == NULL) { + return PP_MakeUndefined(); + } + return ppb_var->VarFromUtf8( + module_id, str.c_str(), nacl::assert_cast<uint32_t>(str.size())); +} + +std::string PluginVar::PPVarToString(const PP_Var& var) { + static const PPB_Var* ppb_var = NULL; + if (ppb_var == NULL) { + ppb_var = static_cast<const PPB_Var*>( + ppapi_proxy::PluginVar::GetInterface()); + } + if (ppb_var == NULL || var.type != PP_VARTYPE_STRING) { + return ""; + } + uint32_t len; + return ppb_var->VarToUtf8(var, &len); +} + +void PluginVar::Print(const PP_Var& var) { + switch (var.type) { + case PP_VARTYPE_UNDEFINED: + DebugPrintf("PP_Var(undefined)"); + break; + case PP_VARTYPE_NULL: + DebugPrintf("PP_Var(null)"); + break; + case PP_VARTYPE_BOOL: + DebugPrintf("PP_Var(bool: %s)", var.value.as_bool ? "true" : "false"); + break; + case PP_VARTYPE_INT32: + DebugPrintf("PP_Var(int32: %"NACL_PRId32")", var.value.as_int); + break; + case PP_VARTYPE_DOUBLE: + DebugPrintf("PP_Var(double: %f)", var.value.as_double); + break; + case PP_VARTYPE_STRING: + { + std::string str = DebugString(var); + DebugPrintf("PP_Var(string: '%*s')", + static_cast<uint32_t>(str.size()), + str.c_str()); + } + case PP_VARTYPE_OBJECT: + DebugPrintf("PP_Var(object: %"NACL_PRIu64")", GetVarId(var)); + break; + case PP_VARTYPE_ARRAY: + case PP_VARTYPE_DICTIONARY: + NACL_NOTREACHED(); + break; + } +} + +} // namespace ppapi_proxy diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_var.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_var.h new file mode 100644 index 0000000..0b7ee16 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_var.h @@ -0,0 +1,40 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_VAR_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_VAR_H_ + +#include <string> + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/portability.h" +#include "ppapi/c/pp_var.h" +#include "ppapi/c/ppb_var.h" + +namespace ppapi_proxy { + +// Implements the plugin side of the PPB_Var interface. +// This implementation also determines how PP_Vars are represented internally +// in the proxied implementation. +class PluginVar { + public: + // Returns an interface pointer suitable to the PPAPI client. + static const PPB_Var* GetInterface(); + + // String helpers. + static PP_Var StringToPPVar(PP_Module module_id, const std::string& str); + static std::string PPVarToString(const PP_Var& var); + + // Printing and debugging. + static void Print(const PP_Var& var); + static std::string DebugString(const PP_Var& var); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(PluginVar); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_VAR_H_ + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_widget.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_widget.cc new file mode 100644 index 0000000..40cd290 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_widget.cc @@ -0,0 +1,145 @@ +// 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/plugin_ppb_widget.h" + +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/plugin_callback.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/dev/ppb_scrollbar_dev.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_input_event.h" +#include "ppapi/c/pp_rect.h" +#include "srpcgen/ppb_rpc.h" + +namespace ppapi_proxy { + +namespace { + +const nacl_abi_size_t kPPRectBytes = + static_cast<nacl_abi_size_t>(sizeof(struct PP_Rect)); + +PP_Bool IsWidget(PP_Resource resource) { + DebugPrintf("PPB_Widget::IsWidget: " + "resource=%"NACL_PRIu32"\n", resource); + + int32_t is_widget = 0; + NaClSrpcError srpc_result = + PpbWidgetRpcClient::PPB_Widget_IsWidget( + GetMainSrpcChannel(), + resource, + &is_widget); + + DebugPrintf("PPB_Widget::IsWidget: %s\n", + NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK && is_widget) + return PP_TRUE; + return PP_FALSE; +} + +PP_Bool Paint( + PP_Resource widget, + const struct PP_Rect* rect, + PP_Resource image) { + DebugPrintf("PPB_Widget::Paint: " + "widget=%"NACL_PRIu32"\n", widget); + + int32_t success = 0; + NaClSrpcError srpc_result = + PpbWidgetRpcClient::PPB_Widget_Paint( + GetMainSrpcChannel(), + widget, + kPPRectBytes, + reinterpret_cast<char*>(const_cast<struct PP_Rect*>(rect)), + image, + &success); + + DebugPrintf("PPB_Widget::Paint: %s\n", + NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK && success) + return PP_TRUE; + return PP_FALSE; +} + +PP_Bool HandleEvent(PP_Resource widget, PP_Resource event) { + DebugPrintf("PPB_Widget::HandleEvent: widget=%"NACL_PRId32", " + "event=%"NACL_PRId32"\n", + widget, event); + + int32_t handled = 0; + NaClSrpcError srpc_result = + PpbWidgetRpcClient::PPB_Widget_HandleEvent(GetMainSrpcChannel(), + widget, + event, + &handled); + + DebugPrintf("PPB_Widget::HandleEvent: %s\n", + NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK && handled) + return PP_TRUE; + return PP_FALSE; +} + +PP_Bool GetLocation( + PP_Resource widget, + struct PP_Rect* location) { + DebugPrintf("PPB_Widget::GetLocation: " + "widget=%"NACL_PRIu32"\n", widget); + + int32_t visible = 0; + nacl_abi_size_t location_size = kPPRectBytes; + NaClSrpcError srpc_result = + PpbWidgetRpcClient::PPB_Widget_GetLocation( + GetMainSrpcChannel(), + widget, + &location_size, + reinterpret_cast<char*>(location), + &visible); + + DebugPrintf("PPB_Widget::GetLocation: %s\n", + NaClSrpcErrorString(srpc_result)); + + if (srpc_result == NACL_SRPC_RESULT_OK && visible && + location_size == kPPRectBytes) + return PP_TRUE; + return PP_FALSE; +} + +void SetLocation( + PP_Resource widget, + const struct PP_Rect* location) { + DebugPrintf("PPB_Widget::SetLocation: " + "widget=%"NACL_PRIu32"\n", widget); + + NaClSrpcError srpc_result = + PpbWidgetRpcClient::PPB_Widget_SetLocation( + GetMainSrpcChannel(), + widget, + kPPRectBytes, + reinterpret_cast<char*>(const_cast<struct PP_Rect*>(location))); + + DebugPrintf("PPB_Widget::SetLocation: %s\n", + NaClSrpcErrorString(srpc_result)); +} + +} // namespace + +const PPB_Widget_Dev* PluginWidget::GetInterface() { + static const PPB_Widget_Dev widget_interface = { + IsWidget, + Paint, + HandleEvent, + GetLocation, + SetLocation + }; + return &widget_interface; +} + +} // namespace ppapi_proxy + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_widget.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_widget.h new file mode 100644 index 0000000..3694a00 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_widget.h @@ -0,0 +1,26 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_WIDGET_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_WIDGET_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "ppapi/c/dev/ppb_widget_dev.h" + +namespace ppapi_proxy { + +// Implements the untrusted side of the PPB_Widget_Dev interface. +class PluginWidget { + public: + PluginWidget(); + static const PPB_Widget_Dev* GetInterface(); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(PluginWidget); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_WIDGET_H_ + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_zoom.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_zoom.cc new file mode 100644 index 0000000..6555c6d --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_zoom.cc @@ -0,0 +1,64 @@ +// 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/plugin_ppb_zoom.h" + +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/plugin_callback.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/dev/ppb_zoom_dev.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" +#include "srpcgen/ppb_rpc.h" + +namespace ppapi_proxy { + +namespace { + +void ZoomChanged(PP_Instance instance, + double factor) { + DebugPrintf("PPB_Zoom::ZoomChanged: " + "instance=%"NACL_PRIu32"\n", instance); + + NaClSrpcError srpc_result = + PpbZoomRpcClient::PPB_Zoom_ZoomChanged( + GetMainSrpcChannel(), + instance, + factor); + + DebugPrintf("PPB_Zoom::ZoomChanged: %s\n", + NaClSrpcErrorString(srpc_result)); +} + +void ZoomLimitsChanged(PP_Instance instance, + double minimum_factor, + double maximum_factor) { + DebugPrintf("PPB_Zoom::ZoomLimitsChanged: " + "instance=%"NACL_PRIu32"\n", instance); + + NaClSrpcError srpc_result = + PpbZoomRpcClient::PPB_Zoom_ZoomLimitsChanged( + GetMainSrpcChannel(), + instance, + minimum_factor, + maximum_factor); + + DebugPrintf("PPB_Zoom::ZoomLimitsChanged: %s\n", + NaClSrpcErrorString(srpc_result)); +} + +} // namespace + +const PPB_Zoom_Dev* PluginZoom::GetInterface() { + static const PPB_Zoom_Dev zoom_interface = { + ZoomChanged, + ZoomLimitsChanged + }; + return &zoom_interface; +} + +} // namespace ppapi_proxy + + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_zoom.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_zoom.h new file mode 100644 index 0000000..c5a2757 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_zoom.h @@ -0,0 +1,26 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_ZOOM_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_ZOOM_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "ppapi/c/dev/ppb_zoom_dev.h" + +namespace ppapi_proxy { + +// Implements the untrusted side of the PPB_Zoom_Dev interface. +class PluginZoom { + public: + PluginZoom(); + static const PPB_Zoom_Dev* GetInterface(); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(PluginZoom); +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_PPB_ZOOM_H_ + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_find_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_find_rpc_server.cc new file mode 100644 index 0000000..f3551dd --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_find_rpc_server.cc @@ -0,0 +1,67 @@ +// 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. +// +// SRPC-abstraction wrappers around PPP_Scrollbar functions. + +#include <string.h> + +#include "native_client/src/include/portability.h" +#include "native_client/src/include/portability_process.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/dev/ppp_find_dev.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/ppp.h" +#include "srpcgen/ppp_rpc.h" + +using ppapi_proxy::DebugPrintf; +using ppapi_proxy::PPPFindInterface; + +void PppFindRpcServer::PPP_Find_StartFind( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Instance instance, + nacl_abi_size_t text_bytes, char* text, + int32_t case_sensitive, + int32_t* supports_find) { + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + NaClSrpcClosureRunner runner(done); + + PP_Bool pp_supports_find = PPPFindInterface()->StartFind( + instance, + text, + case_sensitive ? PP_TRUE : PP_FALSE); + *supports_find = pp_supports_find == PP_TRUE; + + DebugPrintf("PPP_Find::StartFind: pp_supports_find=%d\n", pp_supports_find); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PppFindRpcServer::PPP_Find_SelectFindResult( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Instance instance, + int32_t forward) { + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + NaClSrpcClosureRunner runner(done); + + PPPFindInterface()->SelectFindResult(instance, forward ? PP_TRUE : PP_FALSE); + DebugPrintf("PPP_Find::SelectFindResult\n"); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PppFindRpcServer::PPP_Find_StopFind( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Instance instance) { + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + NaClSrpcClosureRunner runner(done); + + PPPFindInterface()->StopFind(instance); + DebugPrintf("PPP_Find::StopFind\n"); + rpc->result = NACL_SRPC_RESULT_OK; +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_input_event_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_input_event_rpc_server.cc new file mode 100644 index 0000000..f871c6e --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_input_event_rpc_server.cc @@ -0,0 +1,84 @@ +// 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. +// +// SRPC-abstraction wrappers around PPB_InputEvent functions. + +#include <cstring> + +#include "native_client/src/include/portability.h" +#include "native_client/src/include/portability_process.h" +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/shared/ppapi_proxy/input_event_data.h" +#include "native_client/src/shared/ppapi_proxy/object_serialize.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/plugin_ppb_var.h" +#include "native_client/src/shared/ppapi_proxy/plugin_ppb_input_event.h" +#include "native_client/src/shared/ppapi_proxy/plugin_resource.h" +#include "native_client/src/shared/ppapi_proxy/plugin_resource_tracker.h" +#include "native_client/src/shared/ppapi_proxy/untrusted/srpcgen/ppp_rpc.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/pp_var.h" +#include "ppapi/c/ppp.h" +#include "ppapi/c/ppp_input_event.h" + +using nacl::scoped_ptr; +using ppapi_proxy::DebugPrintf; +using ppapi_proxy::DeserializeTo; +using ppapi_proxy::InputEventData; +using ppapi_proxy::PPPInputEventInterface; +using ppapi_proxy::PluginInputEvent; +using ppapi_proxy::PluginResource; +using ppapi_proxy::PluginResourceTracker; + + +void PppInputEventRpcServer::PPP_InputEvent_HandleInputEvent( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Instance instance, + PP_Resource browser_resource, + uint32_t event_data_size, char* event_data, + uint32_t character_text_size, char* character_text_bytes, + // outputs + int32_t* handled) { + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + NaClSrpcClosureRunner runner(done); + *handled = static_cast<int32_t>(PP_FALSE); + + // The browser will immediately release this resource when we return, hence + // we use a browser count of 0. If the NaCl instance calls AddRefResource, + // the ResourceTracker will inform the browser synchronously, so the resource + // will be retained. + scoped_refptr<PluginInputEvent> input_event = + PluginResource::AdoptAsWithNoBrowserCount<PluginInputEvent>( + browser_resource); + // Now deserialize the input event data and initialize the local + // InputEventData with it. Note that we don't actually use the provided + // PP_Resource for anything; we have all the data sent to us immediately to + // avoid too much RPC in input event handling calls. Using the browser- + // provided resource id, however, guarantees our PP_Resource is unique (since + // all other resource ids used in the untrusted side were also provided by + // the browser). + InputEventData data; + std::memcpy(&data, event_data, event_data_size); + PP_Var character_text_var = PP_MakeUndefined(); + DeserializeTo(rpc->channel, character_text_bytes, character_text_size, 1, + &character_text_var); + input_event->Init(data, character_text_var); + + *handled = static_cast<int32_t>( + PPPInputEventInterface()->HandleInputEvent(instance, browser_resource)); + DebugPrintf("PPP_InputEvent::HandleInputEvent: handled=%d\n", handled); + // Now release the input, to match the behavior of the browser. If the NaCl + // instance wants to retain the input event for any reason (e.g. to share it + // to another thread), it must have called AddRefResource by now. If it has + // not, then the input event resource will be deleted from + // PluginResourceTracker's cache, and because the browser refcount was set to + // 0, the resource tracker will *not* tell the browser. When we return, the + // browser decrements its local reference count for us. + PluginResourceTracker::Get()->UnrefResource(browser_resource); + + rpc->result = NACL_SRPC_RESULT_OK; +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_instance_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_instance_rpc_server.cc new file mode 100644 index 0000000..dffe5a9 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_instance_rpc_server.cc @@ -0,0 +1,169 @@ +// 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. +// +// SRPC-abstraction wrappers around PPB_Instance functions. + +#include <string.h> + +#include "native_client/src/include/portability.h" +#include "native_client/src/include/portability_process.h" +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "srpcgen/ppp_rpc.h" +#include "native_client/src/shared/ppapi_proxy/object_serialize.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/plugin_instance_data.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/ppp.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/pp_var.h" +#include "ppapi/c/ppp_instance.h" + +using nacl::scoped_ptr; +using ppapi_proxy::DebugPrintf; +using ppapi_proxy::PPPInstanceInterface; + +namespace { + +// Several of the PPAPI methods return booleans. These boolean values are done +// using SRPC's int32_t, so to be clearer, we define success and failure. +// TODO(sehr): fix SRPC's bool type. +const int32_t kMethodSuccess = 1; +const int32_t kMethodFailure = 0; + +// Build vector of "count" char pointers from a string of NUL-separated tokens. +// Returns NULL on out of memory or parsing error. +const char** GetCharpArray(uint32_t count, char* str, uint32_t total_len) { + const char** array = new const char *[count]; + if (array == NULL) { + return NULL; + } + const char* p = const_cast<const char*>(str); + for (uint32_t i = 0; i < count; ++i) { + array[i] = p; + // Find the end of the current array element. + while ('\0' != *p) { + // We know that p >= str, so the cast preserves sign. + if (total_len <= static_cast<uint32_t>(p - str)) { + // Reached the end of the string before finding NUL. + delete[] array; + return NULL; + } + ++p; + } + // And find the next starting point (if any). + // We know that p >= str, so the cast preserves sign. + if (total_len > static_cast<uint32_t>(p - str)) { + ++p; + } + } + return array; +} + +} // namespace + +void PppInstanceRpcServer::PPP_Instance_DidCreate( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Instance instance, + int32_t argc, + uint32_t argn_bytes, char* argn, + uint32_t argv_bytes, char* argv, + // outputs + int32_t* success) { + ppapi_proxy::PluginInstanceData::DidCreate(instance); + + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + *success = kMethodFailure; + // Deserialize the argv and argn strutures. + scoped_ptr<const char*> argn_copy(GetCharpArray(argc, argn, argn_bytes)); + if (argn_copy.get() == NULL) { + return; + } + scoped_ptr<const char*> argv_copy(GetCharpArray(argc, argv, argv_bytes)); + if (argv_copy.get() == NULL) { + return; + } + bool created = PPPInstanceInterface()->DidCreate(instance, + argc, + argn_copy.get(), + argv_copy.get()); + DebugPrintf("PPP_Instance::DidCreate: created=%d\n", created); + *success = created ? kMethodSuccess : kMethodFailure; + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PppInstanceRpcServer::PPP_Instance_DidDestroy( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Instance instance) { + ppapi_proxy::PluginInstanceData::DidDestroy(instance); + + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + NaClSrpcClosureRunner runner(done); + PPPInstanceInterface()->DidDestroy(instance); + DebugPrintf("PPP_Instance::DidDestroy\n"); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PppInstanceRpcServer::PPP_Instance_DidChangeView( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Instance instance_id, + uint32_t position_count, int32_t* position, + uint32_t clip_count, int32_t* clip) { + const PP_Rect position_rect = + PP_MakeRectFromXYWH(position[0], position[1], position[2], position[3]); + const PP_Rect clip_rect = + PP_MakeRectFromXYWH(clip[0], clip[1], clip[2], clip[3]); + + ppapi_proxy::PluginInstanceData::DidChangeView(instance_id, + position_rect, + clip_rect); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + NaClSrpcClosureRunner runner(done); + if (position_count != 4 || clip_count != 4) { + return; + } + + PPPInstanceInterface()->DidChangeView( + instance_id, &position_rect, &clip_rect); + DebugPrintf("PPP_Instance::DidChangeView\n"); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PppInstanceRpcServer::PPP_Instance_DidChangeFocus( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Instance instance, + bool has_focus) { + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + NaClSrpcClosureRunner runner(done); + PPPInstanceInterface()->DidChangeFocus(instance, + static_cast<PP_Bool>(has_focus)); + DebugPrintf("PPP_Instance::DidChangeFocus\n"); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PppInstanceRpcServer::PPP_Instance_HandleDocumentLoad( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Instance instance, + PP_Resource url_loader, + // outputs + int32_t* success) { + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + NaClSrpcClosureRunner runner(done); + *success = kMethodFailure; + bool handled = + PPPInstanceInterface()->HandleDocumentLoad(instance, url_loader); + DebugPrintf("PPP_Instance::HandleDocumentLoad: handled=%d\n", handled); + *success = handled ? kMethodSuccess : kMethodFailure; + rpc->result = NACL_SRPC_RESULT_OK; +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_messaging_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_messaging_rpc_server.cc new file mode 100644 index 0000000..40c8cb5 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_messaging_rpc_server.cc @@ -0,0 +1,31 @@ +// 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/platform/nacl_check.h" +#include "native_client/src/shared/ppapi_proxy/object_serialize.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/ppp.h" +#include "ppapi/c/ppp_messaging.h" +#include "srpcgen/ppp_rpc.h" + +using ppapi_proxy::DebugPrintf; +using ppapi_proxy::DeserializeTo; +using ppapi_proxy::PPPMessagingInterface; + +void PppMessagingRpcServer::PPP_Messaging_HandleMessage( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + nacl_abi_size_t message_size, char* message_bytes) { + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + NaClSrpcClosureRunner runner(done); + + PP_Var message; + if (!DeserializeTo(rpc->channel, message_bytes, message_size, 1, &message)) + return; + PPPMessagingInterface()->HandleMessage(instance, message); + DebugPrintf("PPP_Instance::HandleMessage\n"); + rpc->result = NACL_SRPC_RESULT_OK; +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_printing_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_printing_rpc_server.cc new file mode 100644 index 0000000..79b0896 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_printing_rpc_server.cc @@ -0,0 +1,124 @@ +// 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. +// +// SRPC-abstraction wrappers around PPP_Printing functions. + +#include <string.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/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/dev/ppp_printing_dev.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/ppp.h" +#include "srpcgen/ppp_rpc.h" + +using ppapi_proxy::DebugPrintf; +using ppapi_proxy::PPPPrintingInterface; + +namespace { + +const nacl_abi_size_t kPPPrintOutputFormatBytes = + static_cast<nacl_abi_size_t>(sizeof(PP_PrintOutputFormat_Dev)); +const nacl_abi_size_t kPPPrintSettingsBytes = + static_cast<nacl_abi_size_t>(sizeof(struct PP_PrintSettings_Dev)); +const nacl_abi_size_t kPPPrintPageNumberRangeBytes = + static_cast<nacl_abi_size_t>(sizeof(struct PP_PrintPageNumberRange_Dev)); + +} // namespace + +void PppPrintingRpcServer::PPP_Printing_QuerySupportedFormats( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Instance instance, + // outputs + nacl_abi_size_t* formats_bytes, char* formats, + int32_t* format_count) { + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + NaClSrpcClosureRunner runner(done); + + PP_PrintOutputFormat_Dev* pp_formats = + PPPPrintingInterface()->QuerySupportedFormats( + instance, + reinterpret_cast<uint32_t*>(format_count)); + if (pp_formats != NULL) { + nacl_abi_size_t formats_bytes_needed = + *format_count * kPPPrintOutputFormatBytes; + if (*formats_bytes >= formats_bytes_needed) { + *formats_bytes = formats_bytes_needed; + memcpy(pp_formats, formats, formats_bytes_needed); + } else { + *format_count = 0; + } + ppapi_proxy::PPBMemoryInterface()->MemFree(pp_formats); + } + + DebugPrintf("PPP_Printing::QuerySupportedFormats: " + "format_count=%"NACL_PRId32"\n", *format_count); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PppPrintingRpcServer::PPP_Printing_Begin( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Instance instance, + nacl_abi_size_t print_settings_bytes, char* print_settings, + // outputs + int32_t* pages_required) { + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + NaClSrpcClosureRunner runner(done); + + if (print_settings_bytes != sizeof(struct PP_PrintSettings_Dev)) + return; + struct PP_PrintSettings_Dev* pp_print_settings = + reinterpret_cast<struct PP_PrintSettings_Dev*>(print_settings); + *pages_required = PPPPrintingInterface()->Begin(instance, pp_print_settings); + + DebugPrintf("PPP_Printing::Begin: pages_required=%"NACL_PRId32"\n", + *pages_required); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PppPrintingRpcServer::PPP_Printing_PrintPages( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Instance instance, + nacl_abi_size_t page_ranges_bytes, char* page_ranges, + int32_t page_range_count, + // outputs + PP_Resource* image_data) { + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + NaClSrpcClosureRunner runner(done); + + if (page_ranges_bytes < kPPPrintPageNumberRangeBytes * page_range_count) + return; + struct PP_PrintPageNumberRange_Dev* pp_page_ranges = + reinterpret_cast<struct PP_PrintPageNumberRange_Dev*>(page_ranges); + *image_data = PPPPrintingInterface()->PrintPages(instance, + pp_page_ranges, + page_range_count); + + DebugPrintf("PPP_Printing::PrintPages: image_data=%"NACL_PRIu32"\n", + *image_data); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PppPrintingRpcServer::PPP_Printing_End( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Instance instance) { + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + NaClSrpcClosureRunner runner(done); + + PPPPrintingInterface()->End(instance); + + DebugPrintf("PPP_Printing::End\n"); + rpc->result = NACL_SRPC_RESULT_OK; +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_rpc_server.cc new file mode 100644 index 0000000..01572c1 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_rpc_server.cc @@ -0,0 +1,154 @@ +// Copyright (c) 2010 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. +// +// SRPC-abstraction wrappers around PPP functions. + +#include <stdarg.h> + +#include "native_client/src/include/portability.h" +#include "native_client/src/include/portability_process.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "ppapi/c/ppp.h" +#include "srpcgen/ppp_rpc.h" + +using ppapi_proxy::DebugPrintf; + +namespace { + +const int kInvalidDesc = -1; + +// In order to close the upcall socket descriptor when we shut down, we +// need to remember it. +// TODO(sehr,polina): This ugly state should be attached to the correct +// data structure for the plugin module. +int upcall_socket_fd = kInvalidDesc; + +// The plugin will make synchronous calls back to the browser on the main +// thread. The service exported from the browser is specified in +// service_description. +bool StartMainSrpcChannel(const char* service_description, + NaClSrpcChannel* channel) { + NaClSrpcService* service = + reinterpret_cast<NaClSrpcService*>(calloc(1, sizeof(*service))); + if (NULL == service) { + return false; + } + if (!NaClSrpcServiceStringCtor(service, service_description)) { + free(service); + return false; + } + channel->client = service; + // Remember the main channel for later calls back from the main thread. + ppapi_proxy::SetMainSrpcChannel(channel); + return true; +} + +void StopMainSrpcChannel() { + NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel(); + NaClSrpcService* service = channel->client; + NaClSrpcServiceDtor(service); + channel->client = NULL; + ppapi_proxy::SetMainSrpcChannel(NULL); +} + +// The plugin will make asynchronous calls to the browser on other threads. +// The service exported on this channel will be gotten by service discovery. +bool StartUpcallSrpcChannel(NaClSrpcImcDescType upcall_channel_desc) { + // Create the upcall srpc client. + if (upcall_channel_desc == kInvalidDesc) { + return false; + } + NaClSrpcChannel* upcall_channel = reinterpret_cast<NaClSrpcChannel*>( + calloc(1, sizeof(*upcall_channel))); + if (NULL == upcall_channel) { + return false; + } + if (!NaClSrpcClientCtor(upcall_channel, upcall_channel_desc)) { + free(upcall_channel); + return false; + } + ppapi_proxy::SetUpcallSrpcChannel(upcall_channel); + upcall_socket_fd = upcall_channel_desc; + return true; +} + +void StopUpcallSrpcChannel() { + NaClSrpcChannel* upcall_channel = ppapi_proxy::GetUpcallSrpcChannel(); + NaClSrpcDtor(upcall_channel); + ppapi_proxy::SetUpcallSrpcChannel(NULL); + close(upcall_socket_fd); + upcall_socket_fd = kInvalidDesc; +} + +} // namespace + +// +// The following methods are the SRPC dispatchers for ppapi/c/ppp.h. +// + +void PppRpcServer::PPP_InitializeModule( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + int32_t pid, + PP_Module module, + NaClSrpcImcDescType upcall_channel_desc, + char* service_description, + int32_t* nacl_pid, + int32_t* success) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + DebugPrintf("PPP_InitializeModule: module=%"NACL_PRIu32": %s\n", + module, service_description); + // Set up the service for calling back into the browser. + if (!StartMainSrpcChannel(const_cast<const char*>(service_description), + rpc->channel)) { + DebugPrintf("PPP_InitializeModule: " + "failed to export service on main channel\n"); + return; + } + // Set up the upcall channel for calling back into the browser. + if (!StartUpcallSrpcChannel(upcall_channel_desc)) { + DebugPrintf("PPP_InitializeModule: " + "failed to construct upcall channel\n"); + StopMainSrpcChannel(); + return; + } + ppapi_proxy::SetModuleIdForSrpcChannel(rpc->channel, module); + *success = ::PPP_InitializeModule(module, ppapi_proxy::GetBrowserInterface); + *nacl_pid = GETPID(); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PppRpcServer::PPP_ShutdownModule(NaClSrpcRpc* rpc, + NaClSrpcClosure* done) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + DebugPrintf("PPP_ShutdownModule\n"); + // We do NOT call ::PPP_ShutdownModule as it cannot do anything useful + // at this point while still having an ability to hang the browser. + ppapi_proxy::UnsetModuleIdForSrpcChannel(rpc->channel); + StopUpcallSrpcChannel(); + // TODO(sehr, polina): do we even need this function? + // Shouldn't the Dtor be called when nexe's main exits? + //StopMainSrpcChannel(); + // Exit the srpc loop. The server won't answer any more requests. + rpc->result = NACL_SRPC_RESULT_BREAK; + DebugPrintf("PPP_ShutdownModule: %s\n", NaClSrpcErrorString(rpc->result)); +} + +void PppRpcServer::PPP_GetInterface(NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + char* interface_name, + int32_t* exports_interface_name) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + DebugPrintf("PPP_GetInterface('%s')\n", interface_name); + // Since the proxy will make calls to proxied interfaces, we need simply + // to know whether the plugin exports a given interface. + const void* plugin_interface = ::PPP_GetInterface(interface_name); + *exports_interface_name = (plugin_interface != NULL); + rpc->result = NACL_SRPC_RESULT_OK; +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_scrollbar_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_scrollbar_rpc_server.cc new file mode 100644 index 0000000..643136c --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_scrollbar_rpc_server.cc @@ -0,0 +1,53 @@ +// 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. +// +// SRPC-abstraction wrappers around PPP_Scrollbar functions. + +#include <string.h> + +#include "native_client/src/include/portability.h" +#include "native_client/src/include/portability_process.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/dev/ppp_scrollbar_dev.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/ppp.h" +#include "srpcgen/ppp_rpc.h" + +using ppapi_proxy::DebugPrintf; +using ppapi_proxy::PPPScrollbarInterface; + +void PppScrollbarRpcServer::PPP_Scrollbar_ValueChanged( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Instance instance, + PP_Resource resource, + int32_t value) { + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + NaClSrpcClosureRunner runner(done); + + PPPScrollbarInterface()->ValueChanged(instance, resource, value); + + DebugPrintf("PPP_Scrollbar::ValueChanged: value=%"NACL_PRId32"\n", value); + rpc->result = NACL_SRPC_RESULT_OK; +} + +void PppScrollbarRpcServer::PPP_Scrollbar_OverlayChanged( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Instance instance, + PP_Resource resource, + int32_t overlay) { + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + NaClSrpcClosureRunner runner(done); + + PPPScrollbarInterface()->OverlayChanged( + instance, resource, overlay ? PP_TRUE : PP_FALSE); + + DebugPrintf("PPP_Scrollbar::OverlayChanged: value=%s\n", + overlay ? "true" : "false"); + rpc->result = NACL_SRPC_RESULT_OK; +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_selection_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_selection_rpc_server.cc new file mode 100644 index 0000000..04df5a8 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_selection_rpc_server.cc @@ -0,0 +1,41 @@ +// 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. +// +// SRPC-abstraction wrappers around PPP_Selection_Dev functions. + +#include <string.h> + +#include "native_client/src/include/portability.h" +#include "native_client/src/include/portability_process.h" +#include "native_client/src/shared/ppapi_proxy/object_serialize.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/dev/ppp_selection_dev.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/ppp.h" +#include "srpcgen/ppp_rpc.h" + +using ppapi_proxy::DebugPrintf; +using ppapi_proxy::PPPSelectionInterface; +using ppapi_proxy::SerializeTo; + +void PppSelectionRpcServer::PPP_Selection_GetSelectedText( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Instance instance, + int32_t html, + // outputs + nacl_abi_size_t* selected_text_bytes, char* selected_text) { + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + NaClSrpcClosureRunner runner(done); + + PP_Bool pp_html = html ? PP_TRUE : PP_FALSE; + PP_Var pp_selected_text = + PPPSelectionInterface()->GetSelectedText(instance, pp_html); + if (!SerializeTo(&pp_selected_text, selected_text, selected_text_bytes)) + return; + + rpc->result = NACL_SRPC_RESULT_OK; +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_widget_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_widget_rpc_server.cc new file mode 100644 index 0000000..a72127e --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_widget_rpc_server.cc @@ -0,0 +1,39 @@ +// 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. +// +// SRPC-abstraction wrappers around PPP_Widget_Dev functions. + +#include <string.h> + +#include "native_client/src/include/portability.h" +#include "native_client/src/include/portability_process.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/dev/ppp_widget_dev.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/ppp.h" +#include "srpcgen/ppp_rpc.h" + +using ppapi_proxy::DebugPrintf; +using ppapi_proxy::PPPWidgetInterface; + +void PppWidgetRpcServer::PPP_Widget_Invalidate( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Instance instance, + PP_Resource resource, + nacl_abi_size_t dirty_rect_bytes, char* dirty_rect) { + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + NaClSrpcClosureRunner runner(done); + + if (dirty_rect_bytes != sizeof(struct PP_Rect)) + return; + + struct PP_Rect* pp_dirty_rect = + reinterpret_cast<struct PP_Rect*>(dirty_rect); + PPPWidgetInterface()->Invalidate(instance, resource, pp_dirty_rect); + + rpc->result = NACL_SRPC_RESULT_OK; +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_zoom_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_zoom_rpc_server.cc new file mode 100644 index 0000000..dbca400 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_zoom_rpc_server.cc @@ -0,0 +1,35 @@ +// 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. +// +// SRPC-abstraction wrappers around PPP_Zoom functions. + +#include <string.h> + +#include "native_client/src/include/portability.h" +#include "native_client/src/include/portability_process.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/dev/ppp_zoom_dev.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/ppp.h" +#include "srpcgen/ppp_rpc.h" + +using ppapi_proxy::DebugPrintf; +using ppapi_proxy::PPPZoomInterface; + +void PppZoomRpcServer::PPP_Zoom_Zoom( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + // inputs + PP_Instance instance, + double factor, + int32_t text_only) { + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + NaClSrpcClosureRunner runner(done); + + PPPZoomInterface()->Zoom(instance, factor, text_only ? PP_TRUE : PP_FALSE); + + DebugPrintf("PPP_Zoom::Zoom"); + rpc->result = NACL_SRPC_RESULT_OK; +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_resource.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_resource.cc new file mode 100644 index 0000000..36598ba --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_resource.cc @@ -0,0 +1,16 @@ +// 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/plugin_resource.h" + +namespace ppapi_proxy { + +PluginResource::PluginResource() { +} + +PluginResource::~PluginResource() { +} + +} // namespace ppapi_proxy + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_resource.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_resource.h new file mode 100644 index 0000000..0415de4 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_resource.h @@ -0,0 +1,149 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_RESOURCE_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_RESOURCE_H_ + +#include "native_client/src/include/nacl_base.h" +#include "native_client/src/include/ref_counted.h" +#include "native_client/src/shared/ppapi_proxy/plugin_resource_tracker.h" +#include "ppapi/c/pp_resource.h" + +namespace ppapi_proxy { + +// If you inherit from resource, make sure you add the class name here. +#define FOR_ALL_RESOURCES(F) \ + F(PluginAudio) \ + F(PluginAudioConfig) \ + F(PluginBuffer) \ + F(PluginFont) \ + F(PluginGraphics2D) \ + F(PluginGraphics3D) \ + F(PluginImageData) \ + F(PluginInputEvent) + +// Forward declaration of PluginResource classes. +#define DECLARE_RESOURCE_CLASS(RESOURCE) class RESOURCE; +FOR_ALL_RESOURCES(DECLARE_RESOURCE_CLASS) +#undef DECLARE_RESOURCE_CLASS + +class PluginResource : public nacl::RefCounted<PluginResource> { + public: + PluginResource(); + virtual ~PluginResource(); + + // Returns NULL if the resource is invalid or is a different type. + template<typename T> + static scoped_refptr<T> GetAs(PP_Resource res) { + // See if we have the resource cached. + scoped_refptr<PluginResource> resource = + PluginResourceTracker::Get()->GetExistingResource(res); + + return resource ? resource->Cast<T>() : NULL; + } + + // Adopt the given PP_Resource as type T. Use this function for resources that + // the browser provides to the plugin with an incremented ref count (i.e., + // calls AddRefResource); it initializes the browser refcount to 1 or + // increments it if the resource already exists. + // Returns NULL if the resource is invalid or is a different type. + template<typename T> + static scoped_refptr<T> AdoptAs(PP_Resource res); + + // Adopt the given PP_Resource as type T. Use this function for resources + // when the browser drops the refcount immediately. These resources are + // typically meant to be cached on the plugin side, with little or no + // interaction back to the browser. For an example, see PluginInputEvent. + // This is like AdoptAs above, except it initializes the browser_refcount to + // 0 for resources that are new to the plugin, and does not increment the + // browser_refcount for resources that exist. + // Returns NULL if the resource is invalid or is a different type. + template<typename T> + static scoped_refptr<T> AdoptAsWithNoBrowserCount(PP_Resource res); + + // Cast the resource into a specified type. This will return NULL if the + // resource does not match the specified type. Specializations of this + // template call into As* functions. + template <typename T> T* Cast() { return NULL; } + + protected: + virtual bool InitFromBrowserResource(PP_Resource resource) = 0; + + private: + // Type-specific getters for individual resource types. These will return + // NULL if the resource does not match the specified type. Used by the Cast() + // function. + #define DEFINE_TYPE_GETTER(RESOURCE) \ + virtual RESOURCE* As##RESOURCE() { return NULL; } + FOR_ALL_RESOURCES(DEFINE_TYPE_GETTER) + #undef DEFINE_TYPE_GETTER + + // Call this macro in the derived class declaration to actually implement the + // type getter. + #define IMPLEMENT_RESOURCE(RESOURCE) \ + virtual RESOURCE* As##RESOURCE() { return this; } + + DISALLOW_COPY_AND_ASSIGN(PluginResource); +}; + +// Cast() specializations. +#define DEFINE_RESOURCE_CAST(Type) \ + template <> inline Type* PluginResource::Cast<Type>() { \ + return As##Type(); \ + } + +FOR_ALL_RESOURCES(DEFINE_RESOURCE_CAST) +#undef DEFINE_RESOURCE_CAST + +#undef FOR_ALL_RESOURCES + +template<typename T> scoped_refptr<T> +PluginResourceTracker::AdoptBrowserResource(PP_Resource res, + size_t browser_refcount) { + ResourceMap::iterator result = live_resources_.find(res); + // Do we have it already? + if (result == live_resources_.end()) { + // No - try to create a new one. + scoped_refptr<T> new_resource = new T(); + if (new_resource->InitFromBrowserResource(res)) { + AddResource(new_resource, res, browser_refcount); + return new_resource; + } else { + return scoped_refptr<T>(); + } + } else { + // Consume more browser refcounts (unless browser_refcount is 0). + result->second.browser_refcount += browser_refcount; + return result->second.resource->Cast<T>(); + } +} + +template<typename T> +scoped_refptr<T> PluginResource::AdoptAs(PP_Resource res) { + // Short-circuit if null resource. + if (!res) + return NULL; + + // Adopt the resource with 1 browser-side refcount. + const size_t browser_refcount = 1; + return PluginResourceTracker::Get()->AdoptBrowserResource<T>( + res, browser_refcount); +} + +template<typename T> +scoped_refptr<T> PluginResource::AdoptAsWithNoBrowserCount(PP_Resource res) { + // Short-circuit if null resource. + if (!res) + return NULL; + + // Adopt the resource with 0 browser-side refcount. + const size_t browser_refcount = 0; + return PluginResourceTracker::Get()->AdoptBrowserResource<T>( + res, browser_refcount); +} + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_RESOURCE_H_ + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_resource_tracker.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_resource_tracker.cc new file mode 100644 index 0000000..3cfad1f --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_resource_tracker.cc @@ -0,0 +1,101 @@ +// 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/plugin_resource_tracker.h" + +#include <limits> +#include <set> + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/plugin_resource.h" +#include "native_client/src/shared/ppapi_proxy/untrusted/srpcgen/ppb_rpc.h" +#include "ppapi/c/pp_resource.h" + +namespace ppapi_proxy { + +PluginResourceTracker::ResourceAndRefCounts::ResourceAndRefCounts( + PluginResource* r, size_t browser_count) + : resource(r), browser_refcount(browser_count), plugin_refcount(1) { +} + +PluginResourceTracker::ResourceAndRefCounts::~ResourceAndRefCounts() { +} + +scoped_refptr<PluginResource> PluginResourceTracker::GetExistingResource( + PP_Resource res) const { + ResourceMap::const_iterator result = live_resources_.find(res); + if (result == live_resources_.end()) + return scoped_refptr<PluginResource>(); + else + return result->second.resource; +} + +PluginResourceTracker::PluginResourceTracker() { +} + +void PluginResourceTracker::AddResource(PluginResource* resource, + PP_Resource id, + size_t browser_refcount) { + // Add the resource with plugin use-count 1. + live_resources_.insert( + std::make_pair(id, ResourceAndRefCounts(resource, browser_refcount))); +} + +bool PluginResourceTracker::AddRefResource(PP_Resource res) { + ResourceMap::iterator i = live_resources_.find(res); + if (i == live_resources_.end()) { + return false; + } else { + // We don't protect against overflow, since a plugin as malicious as to ref + // once per every byte in the address space could have just as well unrefed + // one time too many. + i->second.plugin_refcount++; + if (i->second.browser_refcount == 0) { + // If we don't currently have any refcount with the browser, try to + // obtain one. + i->second.browser_refcount++; + ObtainBrowserResource(res); + } + return true; + } +} + +bool PluginResourceTracker::UnrefResource(PP_Resource res) { + ResourceMap::iterator i = live_resources_.find(res); + if (i != live_resources_.end()) { + i->second.plugin_refcount--; + if (0 == i->second.plugin_refcount) { + size_t browser_refcount = i->second.browser_refcount; + live_resources_.erase(i); + + // Release all browser references. + ReleaseBrowserResource(res, browser_refcount); + } + return true; + } else { + return false; + } +} + +void PluginResourceTracker::ObtainBrowserResource(PP_Resource res) { + if (res) { + NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel(); + PpbCoreRpcClient::PPB_Core_AddRefResource(channel, res); + } +} + +void PluginResourceTracker::ReleaseBrowserResource(PP_Resource res, + size_t browser_refcount) { + // Release all browser references. + if (res && (browser_refcount > 0)) { + NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel(); + PpbCoreRpcClient::ReleaseResourceMultipleTimes(channel, res, + browser_refcount); + } +} + +} // namespace ppapi_proxy + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_resource_tracker.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_resource_tracker.h new file mode 100644 index 0000000..7fc53bd --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_resource_tracker.h @@ -0,0 +1,91 @@ +// 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. + +#ifndef WEBKIT_GLUE_PLUGINS_PEPPER_RESOURCE_TRACKER_H_ +#define WEBKIT_GLUE_PLUGINS_PEPPER_RESOURCE_TRACKER_H_ + +#include <map> +#include <utility> + +#include "native_client/src/include/nacl_base.h" +#include "native_client/src/include/ref_counted.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_resource.h" + +namespace ppapi_proxy { + +class PluginInstance; +class PluginResource; + +// This class maintains a global list of all live pepper resources. It allows +// us to check resource ID validity and to map them to a specific module. +// +// This object is threadsafe. +class PluginResourceTracker { + public: + // Returns the pointer to the singleton object. + static PluginResourceTracker* Get() { + static PluginResourceTracker tracker; + return &tracker; + } + + // PP_Resources -------------------------------------------------------------- + + // Increment resource's plugin refcount. See ResourceAndRefCount. + bool AddRefResource(PP_Resource res); + bool UnrefResource(PP_Resource res); + + private: + friend class PluginResource; + + // Prohibit creation other then by the Singleton class. + PluginResourceTracker(); + + // Adds the given resource to the tracker and assigns it a resource ID, local + // refcount of 1, and initializes the browser reference count to + // |browser_refcount|. Used only by the Resource class. + void AddResource(PluginResource* resource, PP_Resource id, + size_t browser_refcount); + + // The returned pointer will be NULL if there is no resource. Note that this + // return value is a scoped_refptr so that we ensure the resource is valid + // from the point of the lookup to the point that the calling code needs it. + // Otherwise, the plugin could Release() the resource on another thread and + // the object will get deleted out from under us. + scoped_refptr<PluginResource> GetExistingResource(PP_Resource res) const; + + // Get or create a new PluginResource from a browser resource. + // If we are already tracking this resource, we bump its browser_refcount to + // reflect that we took ownership of it. If this is a new resource, we create + // a PluginResource for it with the given browser_refcount. + template<typename T> scoped_refptr<T> AdoptBrowserResource( + PP_Resource res, size_t browser_refcount); + + // Try to get a browser-side refcount for an existing resource. + void ObtainBrowserResource(PP_Resource res); + + // Release browser-side refcount. + void ReleaseBrowserResource(PP_Resource res, size_t refcount); + + // Last assigned resource ID. + PP_Resource last_id_; + + struct ResourceAndRefCounts { + scoped_refptr<PluginResource> resource; + size_t browser_refcount; + size_t plugin_refcount; + ResourceAndRefCounts(PluginResource* r, size_t browser_refcount); + ~ResourceAndRefCounts(); + }; + typedef std::map<PP_Resource, ResourceAndRefCounts> ResourceMap; + ResourceMap live_resources_; + + DISALLOW_COPY_AND_ASSIGN(PluginResourceTracker); +}; + +} // namespace ppapi_proxy + +#endif // WEBKIT_GLUE_PLUGINS_PEPPER_RESOURCE_TRACKER_H_ + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_threading.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_threading.cc new file mode 100644 index 0000000..96567f0 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_threading.cc @@ -0,0 +1,44 @@ +/* + * 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 <pthread.h> + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/shared/ppapi_proxy/ppruntime.h" + + +/* + * This provides a default definition that is overridden in the IRT. + * TODO(mseaborn): Remove this when PPAPI is only supported via the IRT. + * See http://code.google.com/p/nativeclient/issues/detail?id=1691 + */ + +static int thread_create(uintptr_t *tid, + void (*func)(void *thread_argument), + void *thread_argument) { + /* + * We know that newlib and glibc use a small pthread_t type, so we + * do not need to wrap pthread_t values. + */ + NACL_COMPILE_TIME_ASSERT(sizeof(pthread_t) == sizeof(uintptr_t)); + + return pthread_create((pthread_t *) tid, NULL, + (void *(*)(void *thread_argument)) func, + thread_argument); +} + +static int thread_join(uintptr_t tid) { + return pthread_join((pthread_t) tid, NULL); +} + +const static struct PP_ThreadFunctions thread_funcs = { + thread_create, + thread_join +}; + +void PpapiPluginRegisterDefaultThreadCreator() { + PpapiPluginRegisterThreadCreator(&thread_funcs); +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_upcall.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_upcall.cc new file mode 100644 index 0000000..602425d --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_upcall.cc @@ -0,0 +1,71 @@ +// 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. +// +// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING +// +// This is an early draft of background thread support. +// Until it is complete, we assume that all proxy functions +// (except CallOnMainThread) are called on the main PPAPI thread. +// +// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + +#include "native_client/src/shared/ppapi_proxy/plugin_upcall.h" + +#include <pthread.h> +#include <map> + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/ppapi_proxy/plugin_callback.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "ppapi/c/pp_errors.h" +#include "srpcgen/ppp_rpc.h" +#include "srpcgen/upcall.h" + +using ppapi_proxy::CompletionCallbackTable; + +namespace ppapi_proxy { + +namespace { + + class CallOnMainThreadCriticalSection { + static pthread_mutex_t mutex_; + public: + CallOnMainThreadCriticalSection() { pthread_mutex_lock(&mutex_); } + ~CallOnMainThreadCriticalSection() { pthread_mutex_unlock(&mutex_); } + }; + + pthread_mutex_t CallOnMainThreadCriticalSection::mutex_ = + PTHREAD_MUTEX_INITIALIZER; + +} // namespace + +// The call on main thread is implemented via an RPC to the browser side on the +// upcall channel, instead of locally to the plugin. This is to ensure that +// when the callback runs (and potentially calls one of the PPB_ methods +// over RPC), the browser-side is listening. +void PluginUpcallCoreCallOnMainThread(int32_t delay_in_milliseconds, + PP_CompletionCallback callback, + int32_t result) { + // Force PluginUpcallCoreCallOnMainThread, from multiple threads, to occur + // one at a time. + CallOnMainThreadCriticalSection guard; + NaClSrpcChannel* upcall_channel = GetUpcallSrpcChannel(); + if (upcall_channel == NULL) { + DebugPrintf("PluginUpcallCoreCallOnMainThread: NULL channel.\n"); + return; + } + int32_t callback_id = + ppapi_proxy::CompletionCallbackTable::Get()->AddCallback(callback); + if (callback_id == 0) { + DebugPrintf("PluginUpcallCoreCallOnMainThread: NULL callback.\n"); + return; + } + (void) PppUpcallRpcClient::PPB_Core_CallOnMainThread( + upcall_channel, delay_in_milliseconds, callback_id, result); +} + +} // namespace ppapi_proxy diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_upcall.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_upcall.h new file mode 100644 index 0000000..e0b4377 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_upcall.h @@ -0,0 +1,39 @@ +// Copyright (c) 2010 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. +// +// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING +// +// This is an early draft of background thread support. +// Until it is complete, we assume that all functions proxy functions +// (but CallOnMainThread) are called on the main thread. +// +// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_UPCALL_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_UPCALL_H_ + +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_resource.h" + +namespace ppapi_proxy { + +// Initialize the plugin side to allow upcalls (calls to the browser from +// other than the PPAPI main thread). +int32_t PluginUpcallStartup(); + +// Shut down the plugin side for upcalls. +void PluginUpcallShutdown(); + +// The upcall for PPB_Core.CallOnMainThread. +void PluginUpcallCoreCallOnMainThread(int32_t delay_in_milliseconds, + PP_CompletionCallback callback, + int32_t result); + +// The upcall for PPB_Graphics2D.Flush. +int32_t PluginUpcallGraphics2DFlush(PP_Resource graphics_2d, + PP_CompletionCallback callback); + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_UPCALL_H_ diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppapi_proxy.gyp b/ppapi/native_client/src/shared/ppapi_proxy/ppapi_proxy.gyp new file mode 100644 index 0000000..e2089a5 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppapi_proxy.gyp @@ -0,0 +1,68 @@ +# 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. + +{ + 'includes': [ + '../../../build/common.gypi', + ], + 'targets': [ + { + 'target_name': 'nacl_ppapi_browser', + 'type': 'static_library', + 'sources': [ + 'browser_callback.cc', + 'browser_globals.cc', + 'browser_nacl_file_rpc_server.cc', + 'browser_ppb_audio_rpc_server.cc', + 'browser_ppb_audio_config_rpc_server.cc', + 'browser_ppb_core_rpc_server.cc', + 'browser_ppb_cursor_control_rpc_server.cc', + 'browser_ppb_file_io_rpc_server.cc', + 'browser_ppb_file_ref_rpc_server.cc', + 'browser_ppb_file_system_rpc_server.cc', + 'browser_ppb_find_rpc_server.cc', + 'browser_ppb_font_rpc_server.cc', + 'browser_ppb_graphics_2d_rpc_server.cc', + 'browser_ppb_graphics_3d_rpc_server.cc', + 'browser_ppb_image_data_rpc_server.cc', + 'browser_ppb_input_event_rpc_server.cc', + 'browser_ppb_instance_rpc_server.cc', + 'browser_ppb_messaging_rpc_server.cc', + 'browser_ppb_pdf_rpc_server.cc', + 'browser_ppb_rpc_server.cc', + 'browser_ppb_scrollbar_rpc_server.cc', + 'browser_ppb_testing_rpc_server.cc', + 'browser_ppb_url_loader_rpc_server.cc', + 'browser_ppb_url_request_info_rpc_server.cc', + 'browser_ppb_url_response_info_rpc_server.cc', + 'browser_ppb_widget_rpc_server.cc', + 'browser_ppb_zoom_rpc_server.cc', + 'browser_ppp_find.cc', + 'browser_ppp_input_event.cc', + 'browser_ppp_instance.cc', + 'browser_ppp_messaging.cc', + 'browser_ppp_printing.cc', + 'browser_ppp_scrollbar.cc', + 'browser_ppp_selection.cc', + 'browser_ppp_widget.cc', + 'browser_ppp_zoom.cc', + 'browser_ppp.cc', + 'browser_upcall.cc', + 'input_event_data.cc', + 'object_serialize.cc', + 'utility.cc', + # Autogerated files + 'ppp_rpc_client.cc', + 'ppb_rpc_server.cc', + 'upcall_server.cc', + ], + 'include_dirs': [ + '<(DEPTH)/native_client/src/shared/ppapi_proxy/trusted', + ], + 'dependencies': [ + '<(DEPTH)/native_client/src/shared/ppapi/ppapi.gyp:ppapi_c_nacl', + ], + }, + ], +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppapi_proxy.xcodeproj/project.pbxproj b/ppapi/native_client/src/shared/ppapi_proxy/ppapi_proxy.xcodeproj/project.pbxproj new file mode 100644 index 0000000..b927afe --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppapi_proxy.xcodeproj/project.pbxproj @@ -0,0 +1,523 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 0056BE226A3DC2421DD758C0 /* browser_globals.cc in Sources */ = {isa = PBXBuildFile; fileRef = 02742F4BBB94996183E4C3D3 /* browser_globals.cc */; }; + 04B554878D15773880F6291C /* browser_ppb_rpc_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = D12A17DF0A5384DC75ADC56B /* browser_ppb_rpc_server.cc */; }; + 0F006ABC91B01E8239274DFD /* object_serialize.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8EFE3143E0DA442CE75D84A3 /* object_serialize.cc */; }; + 0FA149477FF1CE25E5F986B5 /* browser_upcall.cc in Sources */ = {isa = PBXBuildFile; fileRef = 878CAC37F4CA83E3C47278EB /* browser_upcall.cc */; }; + 16B902D1E9452025F7527023 /* browser_ppb_audio_config_rpc_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = C946F5E02F3E10866CF25F7F /* browser_ppb_audio_config_rpc_server.cc */; }; + 17CFF8B49CFAA750C9DC9181 /* input_event_data.cc in Sources */ = {isa = PBXBuildFile; fileRef = 054155718BC55687504C8CDC /* input_event_data.cc */; }; + 18D43A614E8087126DAAFFA8 /* browser_ppb_audio_rpc_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = 6FF26AEF2569DA12A03AC03D /* browser_ppb_audio_rpc_server.cc */; }; + 198164F53118271B0788C4BF /* browser_ppp_find.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1727BB4719B3012C5DF29029 /* browser_ppp_find.cc */; }; + 1AE450EFA6EAE077B9ED579C /* browser_ppb_find_rpc_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1058473A03FCDFB8675B7AFB /* browser_ppb_find_rpc_server.cc */; }; + 210225D7688E2407B574730B /* browser_ppp_printing.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4CA83840A75E9FFCF6F6864F /* browser_ppp_printing.cc */; }; + 25DA53BED12CAB000634978E /* browser_ppb_instance_rpc_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9745490AE0DE94B3914B9385 /* browser_ppb_instance_rpc_server.cc */; }; + 388EDA19E15B41372C3D8176 /* browser_ppp_instance.cc in Sources */ = {isa = PBXBuildFile; fileRef = 954A1C78906094EF0A43D4A0 /* browser_ppp_instance.cc */; }; + 482615F1C617C24D4CE4C5F5 /* upcall_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = E586202B94DA1B17633C3CAA /* upcall_server.cc */; }; + 514C6878CDBE24736A070BFA /* browser_ppb_graphics_2d_rpc_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = AA821BADD7D8B9F6DB4B772C /* browser_ppb_graphics_2d_rpc_server.cc */; }; + 62C3C674AC1530A8D71F82B3 /* browser_ppp_zoom.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8E1151E1D1A47B47833B6FF5 /* browser_ppp_zoom.cc */; }; + 62F8E66E4E46E00634279259 /* browser_ppb_font_rpc_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = B382D02275604E8ACEC0CE5F /* browser_ppb_font_rpc_server.cc */; }; + 68D578F2B28585560CDA4877 /* browser_ppb_url_loader_rpc_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = EBFC933E4DCEC24DC1FFF025 /* browser_ppb_url_loader_rpc_server.cc */; }; + 6D5BA3D1383500996621E3BF /* browser_ppb_core_rpc_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = D164077C57B92C8AA9F5B126 /* browser_ppb_core_rpc_server.cc */; }; + 76D1F014B6BF136CAB666C3F /* browser_ppb_pdf_rpc_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = 0E9DB20F8E8175502632F60A /* browser_ppb_pdf_rpc_server.cc */; }; + 77B890199B53B99713AE4931 /* browser_ppb_input_event_rpc_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = B7C4ED506C190812D53A0882 /* browser_ppb_input_event_rpc_server.cc */; }; + 80CA814A1E0AC66807B1A1BE /* utility.cc in Sources */ = {isa = PBXBuildFile; fileRef = C765DAFF872F6AF74A788554 /* utility.cc */; }; + 817606546901E110B1AD45FF /* browser_ppb_cursor_control_rpc_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2740BB87A16F3D5D0AB87891 /* browser_ppb_cursor_control_rpc_server.cc */; }; + 8CFC3ED4D0913952E393BF96 /* browser_ppb_scrollbar_rpc_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = CC879F739018986B7F0D5A84 /* browser_ppb_scrollbar_rpc_server.cc */; }; + 8E77BDA60E975A500E0FE873 /* browser_ppb_file_ref_rpc_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = 5B3B734FB2CAAD4CD4604B66 /* browser_ppb_file_ref_rpc_server.cc */; }; + 8EEF79DCD255BF0478823EA3 /* browser_ppb_messaging_rpc_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1B094ED7DE3846B3C7FBFA46 /* browser_ppb_messaging_rpc_server.cc */; }; + 93C2C9A415E4808134746653 /* browser_ppb_graphics_3d_rpc_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = 229CEBE09E36595867F6C6D4 /* browser_ppb_graphics_3d_rpc_server.cc */; }; + 96E05B4813179265FF36260F /* browser_ppb_widget_rpc_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2F9946EAE55747A2779815B9 /* browser_ppb_widget_rpc_server.cc */; }; + 98243B1ABFB0837FB214DF58 /* browser_ppb_image_data_rpc_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = 21C25E77101490EA03171D46 /* browser_ppb_image_data_rpc_server.cc */; }; + 9ABE6B51298951501BCBF57E /* browser_ppb_file_io_rpc_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = 0D0E706FE8FE6E6D28709818 /* browser_ppb_file_io_rpc_server.cc */; }; + A1DABC5CAF545F071EF42390 /* browser_ppp_input_event.cc in Sources */ = {isa = PBXBuildFile; fileRef = 24A88ADA6B81D5D82CA2CD3B /* browser_ppp_input_event.cc */; }; + AC58AD94387F9BC97D786245 /* browser_ppb_file_system_rpc_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7C6D3EA246A126E0FB26E541 /* browser_ppb_file_system_rpc_server.cc */; }; + B19FC986B11ACE4FFD5C2C26 /* browser_ppb_testing_rpc_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BDE5205434B17F6ECB41E35 /* browser_ppb_testing_rpc_server.cc */; }; + B2ADFE08F2B14B20C35C33AC /* browser_ppb_url_response_info_rpc_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = A1A9D876AA2E4C724351CB0F /* browser_ppb_url_response_info_rpc_server.cc */; }; + B612AA5179171C8A8E3ADF78 /* browser_ppb_zoom_rpc_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = 52263F453E31E10EE4A303D6 /* browser_ppb_zoom_rpc_server.cc */; }; + C3EBE571277BBFF1B29D2CA5 /* browser_ppp_selection.cc in Sources */ = {isa = PBXBuildFile; fileRef = 90CEFE0757206DF129C1880E /* browser_ppp_selection.cc */; }; + C405878586E526140E44EDE2 /* ppp_rpc_client.cc in Sources */ = {isa = PBXBuildFile; fileRef = EFEBF2376AF4233BB4E4429D /* ppp_rpc_client.cc */; }; + D3CDE20C6A2F59FAABFD3C03 /* browser_callback.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3E518D95B759DD2DA497A1A2 /* browser_callback.cc */; }; + D5DF308F80DFBAF19652AE13 /* browser_nacl_file_rpc_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D746F15F607698A8F2CA960 /* browser_nacl_file_rpc_server.cc */; }; + DDDA2B0007A6F4934FBAEF7F /* browser_ppp.cc in Sources */ = {isa = PBXBuildFile; fileRef = A4836DC1DA9CA3E8112170CA /* browser_ppp.cc */; }; + E20A40CAFAC6FCAF2283ABB3 /* browser_ppp_messaging.cc in Sources */ = {isa = PBXBuildFile; fileRef = 67B1D495E761A4AFBDD13917 /* browser_ppp_messaging.cc */; }; + E94346D4495815A586DF3AC2 /* ppb_rpc_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = 74702F43338CA7F50AD05C95 /* ppb_rpc_server.cc */; }; + F581F4A962D02B904F4C6313 /* browser_ppp_scrollbar.cc in Sources */ = {isa = PBXBuildFile; fileRef = 49CFB0F1AABC17C51ECE9E4B /* browser_ppp_scrollbar.cc */; }; + F9268C44838705B9DA7F88CD /* browser_ppp_widget.cc in Sources */ = {isa = PBXBuildFile; fileRef = 45B4C6883EA1AA84EACCEE2B /* browser_ppp_widget.cc */; }; + FCF78CC768AAFCB60A9CC4F4 /* browser_ppb_url_request_info_rpc_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = C827451C76BC2FA486D1DC50 /* browser_ppb_url_request_info_rpc_server.cc */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 113EB4B93FBF1C097A8FB54A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 18B5649399A9BCEF14992B2D /* ppapi.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 37976CB5EC445D9088DC63A9; + remoteInfo = ppapi_c_nacl; + }; + 61D9EC26A55712F45FBA0F76 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 18B5649399A9BCEF14992B2D /* ppapi.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = E8A6179E550C8FBBA6FE4E48; + remoteInfo = ppapi_cpp_nacl; + }; + 70B1A9CE3721CBA18B40F5A1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 18B5649399A9BCEF14992B2D /* ppapi.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 0C68FB996E598DF8FB52A61D; + remoteInfo = ppapi_cpp_objects_nacl; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 02742F4BBB94996183E4C3D3 /* browser_globals.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_globals.cc; sourceTree = "<group>"; }; + 054155718BC55687504C8CDC /* input_event_data.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = input_event_data.cc; sourceTree = "<group>"; }; + 0D0E706FE8FE6E6D28709818 /* browser_ppb_file_io_rpc_server.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppb_file_io_rpc_server.cc; sourceTree = "<group>"; }; + 0E9DB20F8E8175502632F60A /* browser_ppb_pdf_rpc_server.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppb_pdf_rpc_server.cc; sourceTree = "<group>"; }; + 1058473A03FCDFB8675B7AFB /* browser_ppb_find_rpc_server.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppb_find_rpc_server.cc; sourceTree = "<group>"; }; + 1727BB4719B3012C5DF29029 /* browser_ppp_find.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppp_find.cc; sourceTree = "<group>"; }; + 18B5649399A9BCEF14992B2D /* ppapi.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ppapi.xcodeproj; path = ../../../../../native_client/src/shared/ppapi/ppapi.xcodeproj; sourceTree = SOURCE_ROOT; }; + 1B094ED7DE3846B3C7FBFA46 /* browser_ppb_messaging_rpc_server.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppb_messaging_rpc_server.cc; sourceTree = "<group>"; }; + 21C25E77101490EA03171D46 /* browser_ppb_image_data_rpc_server.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppb_image_data_rpc_server.cc; sourceTree = "<group>"; }; + 229CEBE09E36595867F6C6D4 /* browser_ppb_graphics_3d_rpc_server.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppb_graphics_3d_rpc_server.cc; sourceTree = "<group>"; }; + 23C102470A58F76D87DC893C /* common.gypi */ = {isa = PBXFileReference; lastKnownFileType = text; name = common.gypi; path = ../../../../../native_client/build/common.gypi; sourceTree = "<group>"; }; + 24A88ADA6B81D5D82CA2CD3B /* browser_ppp_input_event.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppp_input_event.cc; sourceTree = "<group>"; }; + 2740BB87A16F3D5D0AB87891 /* browser_ppb_cursor_control_rpc_server.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppb_cursor_control_rpc_server.cc; sourceTree = "<group>"; }; + 2F9946EAE55747A2779815B9 /* browser_ppb_widget_rpc_server.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppb_widget_rpc_server.cc; sourceTree = "<group>"; }; + 3E518D95B759DD2DA497A1A2 /* browser_callback.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_callback.cc; sourceTree = "<group>"; }; + 45B4C6883EA1AA84EACCEE2B /* browser_ppp_widget.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppp_widget.cc; sourceTree = "<group>"; }; + 49CFB0F1AABC17C51ECE9E4B /* browser_ppp_scrollbar.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppp_scrollbar.cc; sourceTree = "<group>"; }; + 4CA83840A75E9FFCF6F6864F /* browser_ppp_printing.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppp_printing.cc; sourceTree = "<group>"; }; + 4D746F15F607698A8F2CA960 /* browser_nacl_file_rpc_server.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_nacl_file_rpc_server.cc; sourceTree = "<group>"; }; + 52263F453E31E10EE4A303D6 /* browser_ppb_zoom_rpc_server.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppb_zoom_rpc_server.cc; sourceTree = "<group>"; }; + 53B263AD715FBC8DE74A65E4 /* ppapi_proxy.gyp */ = {isa = PBXFileReference; lastKnownFileType = text; path = ppapi_proxy.gyp; sourceTree = "<group>"; }; + 5B3B734FB2CAAD4CD4604B66 /* browser_ppb_file_ref_rpc_server.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppb_file_ref_rpc_server.cc; sourceTree = "<group>"; }; + 67B1D495E761A4AFBDD13917 /* browser_ppp_messaging.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppp_messaging.cc; sourceTree = "<group>"; }; + 6FF26AEF2569DA12A03AC03D /* browser_ppb_audio_rpc_server.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppb_audio_rpc_server.cc; sourceTree = "<group>"; }; + 74702F43338CA7F50AD05C95 /* ppb_rpc_server.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ppb_rpc_server.cc; sourceTree = "<group>"; }; + 7BDE5205434B17F6ECB41E35 /* browser_ppb_testing_rpc_server.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppb_testing_rpc_server.cc; sourceTree = "<group>"; }; + 7C6D3EA246A126E0FB26E541 /* browser_ppb_file_system_rpc_server.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppb_file_system_rpc_server.cc; sourceTree = "<group>"; }; + 8346DD1517DC2BED1C8129D4 /* libnacl_ppapi_browser.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libnacl_ppapi_browser.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 878CAC37F4CA83E3C47278EB /* browser_upcall.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_upcall.cc; sourceTree = "<group>"; }; + 8E1151E1D1A47B47833B6FF5 /* browser_ppp_zoom.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppp_zoom.cc; sourceTree = "<group>"; }; + 8EFE3143E0DA442CE75D84A3 /* object_serialize.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = object_serialize.cc; sourceTree = "<group>"; }; + 90CEFE0757206DF129C1880E /* browser_ppp_selection.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppp_selection.cc; sourceTree = "<group>"; }; + 954A1C78906094EF0A43D4A0 /* browser_ppp_instance.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppp_instance.cc; sourceTree = "<group>"; }; + 9745490AE0DE94B3914B9385 /* browser_ppb_instance_rpc_server.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppb_instance_rpc_server.cc; sourceTree = "<group>"; }; + A1A9D876AA2E4C724351CB0F /* browser_ppb_url_response_info_rpc_server.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppb_url_response_info_rpc_server.cc; sourceTree = "<group>"; }; + A4836DC1DA9CA3E8112170CA /* browser_ppp.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppp.cc; sourceTree = "<group>"; }; + AA821BADD7D8B9F6DB4B772C /* browser_ppb_graphics_2d_rpc_server.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppb_graphics_2d_rpc_server.cc; sourceTree = "<group>"; }; + B382D02275604E8ACEC0CE5F /* browser_ppb_font_rpc_server.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppb_font_rpc_server.cc; sourceTree = "<group>"; }; + B7C4ED506C190812D53A0882 /* browser_ppb_input_event_rpc_server.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppb_input_event_rpc_server.cc; sourceTree = "<group>"; }; + C3477435D8F87A349542A73F /* external_code.gypi */ = {isa = PBXFileReference; lastKnownFileType = text; name = external_code.gypi; path = ../../../../../native_client/build/external_code.gypi; sourceTree = "<group>"; }; + C765DAFF872F6AF74A788554 /* utility.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = utility.cc; sourceTree = "<group>"; }; + C827451C76BC2FA486D1DC50 /* browser_ppb_url_request_info_rpc_server.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppb_url_request_info_rpc_server.cc; sourceTree = "<group>"; }; + C946F5E02F3E10866CF25F7F /* browser_ppb_audio_config_rpc_server.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppb_audio_config_rpc_server.cc; sourceTree = "<group>"; }; + CC879F739018986B7F0D5A84 /* browser_ppb_scrollbar_rpc_server.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppb_scrollbar_rpc_server.cc; sourceTree = "<group>"; }; + D12A17DF0A5384DC75ADC56B /* browser_ppb_rpc_server.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppb_rpc_server.cc; sourceTree = "<group>"; }; + D164077C57B92C8AA9F5B126 /* browser_ppb_core_rpc_server.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppb_core_rpc_server.cc; sourceTree = "<group>"; }; + E586202B94DA1B17633C3CAA /* upcall_server.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = upcall_server.cc; sourceTree = "<group>"; }; + EBFC933E4DCEC24DC1FFF025 /* browser_ppb_url_loader_rpc_server.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_ppb_url_loader_rpc_server.cc; sourceTree = "<group>"; }; + EFEBF2376AF4233BB4E4429D /* ppp_rpc_client.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ppp_rpc_client.cc; sourceTree = "<group>"; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + C234E96F6068687070C859F0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 0159C1A8B53C236453216FC1 /* Build */ = { + isa = PBXGroup; + children = ( + 23C102470A58F76D87DC893C /* common.gypi */, + C3477435D8F87A349542A73F /* external_code.gypi */, + 53B263AD715FBC8DE74A65E4 /* ppapi_proxy.gyp */, + ); + name = Build; + sourceTree = "<group>"; + }; + 6D41FC14F36382B2787AA5D1 /* Products */ = { + isa = PBXGroup; + children = ( + 8346DD1517DC2BED1C8129D4 /* libnacl_ppapi_browser.a */, + ); + name = Products; + sourceTree = "<group>"; + }; + 844C08F5BC79B244E3156932 /* Projects */ = { + isa = PBXGroup; + children = ( + 18B5649399A9BCEF14992B2D /* ppapi.xcodeproj */, + ); + name = Projects; + sourceTree = "<group>"; + }; + 97BFF17E51B8AA74051B12AE = { + isa = PBXGroup; + children = ( + BD8446F5E8D2D54DC0B68AD6 /* Source */, + 844C08F5BC79B244E3156932 /* Projects */, + 6D41FC14F36382B2787AA5D1 /* Products */, + 0159C1A8B53C236453216FC1 /* Build */, + ); + sourceTree = "<group>"; + }; + BD8446F5E8D2D54DC0B68AD6 /* Source */ = { + isa = PBXGroup; + children = ( + 3E518D95B759DD2DA497A1A2 /* browser_callback.cc */, + 02742F4BBB94996183E4C3D3 /* browser_globals.cc */, + 4D746F15F607698A8F2CA960 /* browser_nacl_file_rpc_server.cc */, + C946F5E02F3E10866CF25F7F /* browser_ppb_audio_config_rpc_server.cc */, + 6FF26AEF2569DA12A03AC03D /* browser_ppb_audio_rpc_server.cc */, + D164077C57B92C8AA9F5B126 /* browser_ppb_core_rpc_server.cc */, + 2740BB87A16F3D5D0AB87891 /* browser_ppb_cursor_control_rpc_server.cc */, + 0D0E706FE8FE6E6D28709818 /* browser_ppb_file_io_rpc_server.cc */, + 5B3B734FB2CAAD4CD4604B66 /* browser_ppb_file_ref_rpc_server.cc */, + 7C6D3EA246A126E0FB26E541 /* browser_ppb_file_system_rpc_server.cc */, + 1058473A03FCDFB8675B7AFB /* browser_ppb_find_rpc_server.cc */, + B382D02275604E8ACEC0CE5F /* browser_ppb_font_rpc_server.cc */, + AA821BADD7D8B9F6DB4B772C /* browser_ppb_graphics_2d_rpc_server.cc */, + 229CEBE09E36595867F6C6D4 /* browser_ppb_graphics_3d_rpc_server.cc */, + 21C25E77101490EA03171D46 /* browser_ppb_image_data_rpc_server.cc */, + B7C4ED506C190812D53A0882 /* browser_ppb_input_event_rpc_server.cc */, + 9745490AE0DE94B3914B9385 /* browser_ppb_instance_rpc_server.cc */, + 1B094ED7DE3846B3C7FBFA46 /* browser_ppb_messaging_rpc_server.cc */, + 0E9DB20F8E8175502632F60A /* browser_ppb_pdf_rpc_server.cc */, + D12A17DF0A5384DC75ADC56B /* browser_ppb_rpc_server.cc */, + CC879F739018986B7F0D5A84 /* browser_ppb_scrollbar_rpc_server.cc */, + 7BDE5205434B17F6ECB41E35 /* browser_ppb_testing_rpc_server.cc */, + EBFC933E4DCEC24DC1FFF025 /* browser_ppb_url_loader_rpc_server.cc */, + C827451C76BC2FA486D1DC50 /* browser_ppb_url_request_info_rpc_server.cc */, + A1A9D876AA2E4C724351CB0F /* browser_ppb_url_response_info_rpc_server.cc */, + 2F9946EAE55747A2779815B9 /* browser_ppb_widget_rpc_server.cc */, + 52263F453E31E10EE4A303D6 /* browser_ppb_zoom_rpc_server.cc */, + A4836DC1DA9CA3E8112170CA /* browser_ppp.cc */, + 1727BB4719B3012C5DF29029 /* browser_ppp_find.cc */, + 24A88ADA6B81D5D82CA2CD3B /* browser_ppp_input_event.cc */, + 954A1C78906094EF0A43D4A0 /* browser_ppp_instance.cc */, + 67B1D495E761A4AFBDD13917 /* browser_ppp_messaging.cc */, + 4CA83840A75E9FFCF6F6864F /* browser_ppp_printing.cc */, + 49CFB0F1AABC17C51ECE9E4B /* browser_ppp_scrollbar.cc */, + 90CEFE0757206DF129C1880E /* browser_ppp_selection.cc */, + 45B4C6883EA1AA84EACCEE2B /* browser_ppp_widget.cc */, + 8E1151E1D1A47B47833B6FF5 /* browser_ppp_zoom.cc */, + 878CAC37F4CA83E3C47278EB /* browser_upcall.cc */, + 054155718BC55687504C8CDC /* input_event_data.cc */, + 8EFE3143E0DA442CE75D84A3 /* object_serialize.cc */, + 74702F43338CA7F50AD05C95 /* ppb_rpc_server.cc */, + EFEBF2376AF4233BB4E4429D /* ppp_rpc_client.cc */, + E586202B94DA1B17633C3CAA /* upcall_server.cc */, + C765DAFF872F6AF74A788554 /* utility.cc */, + ); + name = Source; + sourceTree = "<group>"; + }; + D7C37A4B20C9D9A40CD5472D /* Products */ = { + isa = PBXGroup; + children = ( + CED0CFA55B4E95CCB1EC5851 /* libppapi_cpp_objects_nacl.a */, + 6C4098E0DCD20F9E9083599B /* libppapi_cpp_nacl.a */, + ); + name = Products; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + A69A7B7DC20908928BE34654 /* nacl_ppapi_browser */ = { + isa = PBXNativeTarget; + buildConfigurationList = C25021B8DA4E5D0272B81FE5 /* Build configuration list for PBXNativeTarget "nacl_ppapi_browser" */; + buildPhases = ( + 25F90DD75A7622D708C8209F /* Sources */, + C234E96F6068687070C859F0 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + E34675CE92FF60175845EF23 /* PBXTargetDependency */, + ); + name = nacl_ppapi_browser; + productName = nacl_ppapi_browser; + productReference = 8346DD1517DC2BED1C8129D4 /* libnacl_ppapi_browser.a */; + productType = "com.apple.product-type.library.static"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 3297DFFD49F6ABFA7F55EF65 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + }; + buildConfigurationList = AD809D91CAF48A08D0115A64 /* Build configuration list for PBXProject "ppapi_proxy" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + mainGroup = 97BFF17E51B8AA74051B12AE; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = D7C37A4B20C9D9A40CD5472D /* Products */; + ProjectRef = 18B5649399A9BCEF14992B2D /* ppapi.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + A69A7B7DC20908928BE34654 /* nacl_ppapi_browser */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + 6C4098E0DCD20F9E9083599B /* libppapi_cpp_nacl.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libppapi_cpp_nacl.a; + remoteRef = 61D9EC26A55712F45FBA0F76 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + CED0CFA55B4E95CCB1EC5851 /* libppapi_cpp_objects_nacl.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libppapi_cpp_objects_nacl.a; + remoteRef = 70B1A9CE3721CBA18B40F5A1 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXSourcesBuildPhase section */ + 25F90DD75A7622D708C8209F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D3CDE20C6A2F59FAABFD3C03 /* browser_callback.cc in Sources */, + 0056BE226A3DC2421DD758C0 /* browser_globals.cc in Sources */, + D5DF308F80DFBAF19652AE13 /* browser_nacl_file_rpc_server.cc in Sources */, + 18D43A614E8087126DAAFFA8 /* browser_ppb_audio_rpc_server.cc in Sources */, + 16B902D1E9452025F7527023 /* browser_ppb_audio_config_rpc_server.cc in Sources */, + 6D5BA3D1383500996621E3BF /* browser_ppb_core_rpc_server.cc in Sources */, + 817606546901E110B1AD45FF /* browser_ppb_cursor_control_rpc_server.cc in Sources */, + 9ABE6B51298951501BCBF57E /* browser_ppb_file_io_rpc_server.cc in Sources */, + 8E77BDA60E975A500E0FE873 /* browser_ppb_file_ref_rpc_server.cc in Sources */, + AC58AD94387F9BC97D786245 /* browser_ppb_file_system_rpc_server.cc in Sources */, + 1AE450EFA6EAE077B9ED579C /* browser_ppb_find_rpc_server.cc in Sources */, + 62F8E66E4E46E00634279259 /* browser_ppb_font_rpc_server.cc in Sources */, + 514C6878CDBE24736A070BFA /* browser_ppb_graphics_2d_rpc_server.cc in Sources */, + 93C2C9A415E4808134746653 /* browser_ppb_graphics_3d_rpc_server.cc in Sources */, + 98243B1ABFB0837FB214DF58 /* browser_ppb_image_data_rpc_server.cc in Sources */, + 77B890199B53B99713AE4931 /* browser_ppb_input_event_rpc_server.cc in Sources */, + 25DA53BED12CAB000634978E /* browser_ppb_instance_rpc_server.cc in Sources */, + 8EEF79DCD255BF0478823EA3 /* browser_ppb_messaging_rpc_server.cc in Sources */, + 76D1F014B6BF136CAB666C3F /* browser_ppb_pdf_rpc_server.cc in Sources */, + 04B554878D15773880F6291C /* browser_ppb_rpc_server.cc in Sources */, + 8CFC3ED4D0913952E393BF96 /* browser_ppb_scrollbar_rpc_server.cc in Sources */, + B19FC986B11ACE4FFD5C2C26 /* browser_ppb_testing_rpc_server.cc in Sources */, + 68D578F2B28585560CDA4877 /* browser_ppb_url_loader_rpc_server.cc in Sources */, + FCF78CC768AAFCB60A9CC4F4 /* browser_ppb_url_request_info_rpc_server.cc in Sources */, + B2ADFE08F2B14B20C35C33AC /* browser_ppb_url_response_info_rpc_server.cc in Sources */, + 96E05B4813179265FF36260F /* browser_ppb_widget_rpc_server.cc in Sources */, + B612AA5179171C8A8E3ADF78 /* browser_ppb_zoom_rpc_server.cc in Sources */, + 198164F53118271B0788C4BF /* browser_ppp_find.cc in Sources */, + A1DABC5CAF545F071EF42390 /* browser_ppp_input_event.cc in Sources */, + 388EDA19E15B41372C3D8176 /* browser_ppp_instance.cc in Sources */, + E20A40CAFAC6FCAF2283ABB3 /* browser_ppp_messaging.cc in Sources */, + 210225D7688E2407B574730B /* browser_ppp_printing.cc in Sources */, + F581F4A962D02B904F4C6313 /* browser_ppp_scrollbar.cc in Sources */, + C3EBE571277BBFF1B29D2CA5 /* browser_ppp_selection.cc in Sources */, + F9268C44838705B9DA7F88CD /* browser_ppp_widget.cc in Sources */, + 62C3C674AC1530A8D71F82B3 /* browser_ppp_zoom.cc in Sources */, + DDDA2B0007A6F4934FBAEF7F /* browser_ppp.cc in Sources */, + 0FA149477FF1CE25E5F986B5 /* browser_upcall.cc in Sources */, + 17CFF8B49CFAA750C9DC9181 /* input_event_data.cc in Sources */, + 0F006ABC91B01E8239274DFD /* object_serialize.cc in Sources */, + 80CA814A1E0AC66807B1A1BE /* utility.cc in Sources */, + C405878586E526140E44EDE2 /* ppp_rpc_client.cc in Sources */, + E94346D4495815A586DF3AC2 /* ppb_rpc_server.cc in Sources */, + 482615F1C617C24D4CE4C5F5 /* upcall_server.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + E34675CE92FF60175845EF23 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = ppapi_c_nacl; + targetProxy = 113EB4B93FBF1C097A8FB54A /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 08D2E2BCB87B795040D352DF /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + DEAD_CODE_STRIPPING = YES; + EXECUTABLE_PREFIX = lib; + GCC_CW_ASM_SYNTAX = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_CPP_EXCEPTIONS = NO; + GCC_ENABLE_CPP_RTTI = NO; + GCC_ENABLE_PASCAL_STRINGS = NO; + GCC_INLINES_ARE_PRIVATE_EXTERN = YES; + GCC_OBJC_CALL_CXX_CDTORS = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "\"NACL_BLOCK_SHIFT=5\"", + "\"NACL_BLOCK_SIZE=32\"", + "\"NACL_LINUX=0\"", + "\"NACL_OSX=1\"", + "\"NACL_WINDOWS=0\"", + "\"__STDC_FORMAT_MACROS\"", + "\"NACL_STANDALONE=1\"", + "\"NACL_TARGET_SUBARCH=32\"", + "\"NACL_TARGET_ARCH=x86\"", + "\"NACL_BUILD_SUBARCH=32\"", + "\"NACL_BUILD_ARCH=x86\"", + "\"NDEBUG\"", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GCC_THREADSAFE_STATICS = NO; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_VERSION = 4.2; + GCC_WARN_ABOUT_MISSING_NEWLINE = YES; + HEADER_SEARCH_PATHS = ( + ../../../../../native_client/src/third_party, + ../../../../.., + ../../../../../ppapi/native_client/src/shared/ppapi_proxy/trusted, + ../../../../../ppapi, + ); + MACOSX_DEPLOYMENT_TARGET = 10.4; + PREBINDING = NO; + PRODUCT_NAME = nacl_ppapi_browser; + SDKROOT = macosx10.5; + USE_HEADERMAP = NO; + WARNING_CFLAGS = ( + "-Wall", + "-Wendif-labels", + "-Wno-long-long", + "-pedantic", + "-Wextra", + "-Wno-long-long", + "-Wswitch-enum", + "-Wsign-compare", + ); + }; + name = Release; + }; + 321B2CF9D87D4161EE304D50 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + EXECUTABLE_PREFIX = lib; + GCC_CW_ASM_SYNTAX = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_CPP_EXCEPTIONS = NO; + GCC_ENABLE_CPP_RTTI = NO; + GCC_ENABLE_PASCAL_STRINGS = NO; + GCC_INLINES_ARE_PRIVATE_EXTERN = YES; + GCC_OBJC_CALL_CXX_CDTORS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "\"NACL_BLOCK_SHIFT=5\"", + "\"NACL_BLOCK_SIZE=32\"", + "\"NACL_LINUX=0\"", + "\"NACL_OSX=1\"", + "\"NACL_WINDOWS=0\"", + "\"__STDC_FORMAT_MACROS\"", + "\"NACL_STANDALONE=1\"", + "\"NACL_TARGET_SUBARCH=32\"", + "\"NACL_TARGET_ARCH=x86\"", + "\"NACL_BUILD_SUBARCH=32\"", + "\"NACL_BUILD_ARCH=x86\"", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GCC_THREADSAFE_STATICS = NO; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_VERSION = 4.2; + GCC_WARN_ABOUT_MISSING_NEWLINE = YES; + HEADER_SEARCH_PATHS = ( + ../../../../../native_client/src/third_party, + ../../../../.., + ../../../../../ppapi/native_client/src/shared/ppapi_proxy/trusted, + ../../../../../ppapi, + ); + MACOSX_DEPLOYMENT_TARGET = 10.4; + PREBINDING = NO; + PRODUCT_NAME = nacl_ppapi_browser; + SDKROOT = macosx10.5; + USE_HEADERMAP = NO; + WARNING_CFLAGS = ( + "-Wall", + "-Wendif-labels", + "-Wno-long-long", + "-pedantic", + "-Wextra", + "-Wno-long-long", + "-Wswitch-enum", + "-Wsign-compare", + ); + }; + name = Debug; + }; + 67A97A08FD7FDEB3C11B6FA9 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + INTERMEDIATE_DIR = "$(PROJECT_DERIVED_FILE_DIR)/$(CONFIGURATION)"; + SHARED_INTERMEDIATE_DIR = "$(SYMROOT)/DerivedSources/$(CONFIGURATION)"; + SYMROOT = ../../../../../xcodebuild; + }; + name = Debug; + }; + 69794B36E89AEABCE8BAF3BD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + INTERMEDIATE_DIR = "$(PROJECT_DERIVED_FILE_DIR)/$(CONFIGURATION)"; + SHARED_INTERMEDIATE_DIR = "$(SYMROOT)/DerivedSources/$(CONFIGURATION)"; + SYMROOT = ../../../../../xcodebuild; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + AD809D91CAF48A08D0115A64 /* Build configuration list for PBXProject "ppapi_proxy" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 67A97A08FD7FDEB3C11B6FA9 /* Debug */, + 69794B36E89AEABCE8BAF3BD /* Release */, + ); + defaultConfigurationIsVisible = 1; + defaultConfigurationName = Debug; + }; + C25021B8DA4E5D0272B81FE5 /* Build configuration list for PBXNativeTarget "nacl_ppapi_browser" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 321B2CF9D87D4161EE304D50 /* Debug */, + 08D2E2BCB87B795040D352DF /* Release */, + ); + defaultConfigurationIsVisible = 1; + defaultConfigurationName = Debug; + }; +/* End XCConfigurationList section */ + }; + rootObject = 3297DFFD49F6ABFA7F55EF65 /* Project object */; +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppb.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppb.srpc new file mode 100644 index 0000000..91e7679 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppb.srpc @@ -0,0 +1,18 @@ +# Copyright (c) 2010 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. + +# RPC method used to implement PPB_GetInterface method. +# See ppapi/c/ppb.h for interface details. +{ + 'name': 'PpbRpc', + 'rpcs': [ + # Checks whether the browser exports a specified interface name. + {'name': 'PPB_GetInterface', + 'inputs': [['interface_name', 'string'], + ], + 'outputs': [['exports_interface_name', 'int32_t'], + ] + }, + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppb_audio.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppb_audio.srpc new file mode 100755 index 0000000..8e97cfc --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppb_audio.srpc @@ -0,0 +1,49 @@ +# Copyright (c) 2010 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. + +# This file declares the RPC methods used to implement PPB_Audio +# calls from the plugin. The functions are described in +# ppapi/c/ppb_audio.h. +{ + 'name': 'PpbAudioRpc', + 'rpcs': [ + # Implements a call to create an audio resource. + # Returns descriptors for memory window, sync socket. + {'name': 'PPB_Audio_Create', + 'inputs': [['instance', 'PP_Instance'], + ['config', 'PP_Resource'], + ], + 'outputs': [['out_resource', 'PP_Resource'], + ] + }, + # Implements a call to determine IsAudio. + {'name': 'PPB_Audio_IsAudio', + 'inputs': [['resource', 'PP_Resource'], + ], + 'outputs': [['out_bool', 'int32_t'], + ] + }, + # Implements a call to get current config as resource. + {'name': 'PPB_Audio_GetCurrentConfig', + 'inputs': [['resource', 'PP_Resource'], + ], + 'outputs': [['out_resource', 'PP_Resource'], + ] + }, + # Implements a call to stop playback. + {'name': 'PPB_Audio_StopPlayback', + 'inputs': [['resource', 'PP_Resource'], + ], + 'outputs': [['out_bool', 'int32_t'], + ] + }, + # Implements a call to start playback. + {'name': 'PPB_Audio_StartPlayback', + 'inputs': [['resource', 'PP_Resource'], + ], + 'outputs': [['out_bool', 'int32_t'], + ] + }, + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppb_audio_config.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppb_audio_config.srpc new file mode 100755 index 0000000..95a8a99 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppb_audio_config.srpc @@ -0,0 +1,50 @@ +# Copyright (c) 2010 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. + +# This file declares the RPC methods used to implement PPB_AudioConfig +# calls from the plugin. The functions are described in +# ppapi/c/ppb_audio_config.h. +{ + 'name': 'PpbAudioConfigRpc', + 'rpcs': [ + # Implements a call to create an audio configuration for stereo output. + {'name': 'PPB_AudioConfig_CreateStereo16Bit', + 'inputs': [['instance', 'PP_Instance'], + ['sample_rate', 'int32_t'], + ['sample_frame_count', 'int32_t'], + ], + 'outputs': [['resource', 'PP_Resource'], + ] + }, + # Implements a call to check if this is an AudioConfig. + {'name': 'PPB_AudioConfig_IsAudioConfig', + 'inputs': [['resource', 'PP_Resource'], + ], + 'outputs': [['out_bool', 'int32_t'] + ] + }, + # Implements a call to get recommended sample frame count. + {'name': 'PPB_AudioConfig_RecommendSampleFrameCount', + 'inputs': [['request_sample_rate', 'int32_t'], + ['request_sample_frame_count', 'int32_t'], + ], + 'outputs': [['out_sample_frame_count', 'int32_t'] + ] + }, + # Implements a call to get the sample rate. + {'name': 'PPB_AudioConfig_GetSampleRate', + 'inputs': [['resource', 'PP_Resource'], + ], + 'outputs': [['sample_rate', 'int32_t'] + ] + }, + # Implements a call to get the obtained sample frame count. + {'name': 'PPB_AudioConfig_GetSampleFrameCount', + 'inputs': [['resource', 'PP_Resource'], + ], + 'outputs': [['sample_frame_count', 'int32_t'], + ] + }, + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppb_core.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppb_core.srpc new file mode 100755 index 0000000..b95a4f5 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppb_core.srpc @@ -0,0 +1,57 @@ +# Copyright (c) 2010 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. + +# RPC methods used to implement PPB_Core interface. +# See ppapi/c/ppb_core.h for interface details. +{ + 'name': 'PpbCoreRpc', + 'rpcs': [ + # Implements calls to increment the reference count on a resource. + {'name': 'PPB_Core_AddRefResource', + 'inputs': [['resource', 'PP_Resource'], + ], + 'outputs': [] + }, + # Implements calls to decrement the reference count on a resource. + {'name': 'PPB_Core_ReleaseResource', + 'inputs': [['resource', 'PP_Resource'], + ], + 'outputs': [] + }, + # Implements calls to decrement more than one reference count on a + # resource. This does not exist in PPB_Core, we implement it as an + # optimization. + {'name': 'ReleaseResourceMultipleTimes', + 'inputs': [['resource', 'PP_Resource'], + ['count', 'int32_t'] + ], + 'outputs': [] + }, + + # MemAlloc and MemFree do not require RPCs to the browser. + + # Implements calls to get the time. + {'name': 'PPB_Core_GetTime', + 'inputs': [], + 'outputs': [['time', 'double'], + ] + }, + # Implements calls to get the browser time ticks. + {'name': 'PPB_Core_GetTimeTicks', + 'inputs': [], + 'outputs': [['time_ticks', 'double'], + ] + }, + # To be called from the main thread only! + {'name': 'PPB_Core_CallOnMainThread', + 'inputs': [['delay_in_milliseconds', 'int32_t'], # int32_t + ['callback_id', 'int32_t'], # PP_CompletionCallback + ['result', 'int32_t'], # int32_t + ], + 'outputs': [] + }, + + # IsMainThread does not require PRCs to the browser. + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppb_cursor_control.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppb_cursor_control.srpc new file mode 100644 index 0000000..1b1115b --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppb_cursor_control.srpc @@ -0,0 +1,45 @@ +# 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. +# +# RPC methods used to implement PPB_CursorControl calls from the plugin. +# See ppapi/c/ppb_cursor_control_dev.h for interface details. + +{ + 'name': 'PpbCursorControlRpc', + 'rpcs': [ + {'name': 'PPB_CursorControl_SetCursor', + 'inputs': [['instance', 'PP_Instance'], # PP_Instance + ['type', 'int32_t'], # PP_CursorType_Dev + ['custom_image', 'PP_Resource'], # PP_Resource + ['hot_spot', 'char[]'], # PP_Point + ], + 'outputs': [['success', 'int32_t'], # PP_Bool + ] + }, + {'name': 'PPB_CursorControl_LockCursor', + 'inputs': [['instance', 'PP_Instance'], # PP_Instance + ], + 'outputs': [['success', 'int32_t'], # PP_Bool + ] + }, + {'name': 'PPB_CursorControl_UnlockCursor', + 'inputs': [['instance', 'PP_Instance'], # PP_Instance + ], + 'outputs': [['success', 'int32_t'], # PP_Bool + ] + }, + {'name': 'PPB_CursorControl_HasCursorLock', + 'inputs': [['instance', 'PP_Instance'], # PP_Instance + ], + 'outputs': [['success', 'int32_t'], # PP_Bool + ] + }, + {'name': 'PPB_CursorControl_CanLockCursor', + 'inputs': [['instance', 'PP_Instance'], # PP_Instance + ], + 'outputs': [['success', 'int32_t'], # PP_Bool + ] + }, + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppb_file_io.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppb_file_io.srpc new file mode 100644 index 0000000..470cb4d8 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppb_file_io.srpc @@ -0,0 +1,91 @@ +# 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. + +# RPC methods used to implement PPB_FileIO calls from the plugin. +# See ppapi/c/ppb_file_io.h for interface details. + +{ + 'name': 'PpbFileIORpc', + 'rpcs': [ + {'name': 'PPB_FileIO_Create', + 'inputs': [['instance', 'PP_Instance'], + ], + 'outputs': [['resource', 'PP_Resource'], + ] + }, + {'name': 'PPB_FileIO_IsFileIO', + 'inputs': [['resource', 'PP_Resource'], + ], + 'outputs': [['success', 'int32_t'], # PP_Bool + ] + }, + {'name': 'PPB_FileIO_Open', + 'inputs': [['file_io', 'PP_Resource'], + ['file_ref', 'PP_Resource'], + ['open_flags', 'int32_t'], + ['callback_id', 'int32_t'], + ], + 'outputs': [['pp_error', 'int32_t'], + ] + }, + {'name': 'PPB_FileIO_Query', + 'inputs': [['file_io', 'PP_Resource'], + ['bytes_to_read', 'int32_t'], + ['callback_id', 'int32_t'], + ], + 'outputs': [['info', 'char[]'], # PP_FileInfo + ['pp_error', 'int32_t'], + ] + }, + {'name': 'PPB_FileIO_Touch', + 'inputs': [['file_io', 'PP_Resource'], + ['last_access_time', 'double'], # PP_Time + ['last_modified_time', 'double'], # PP_Time + ['callback_id', 'int32_t'], + ], + 'outputs': [['pp_error', 'int32_t'], + ] + }, + {'name': 'PPB_FileIO_Read', + 'inputs': [['file_io', 'PP_Resource'], + ['offset', 'int64_t'], + ['bytes_to_read', 'int32_t'], + ['callback_id', 'int32_t'], + ], + 'outputs': [['buffer', 'char[]'], + ['pp_error_or_bytes', 'int32_t'], + ] + }, + {'name': 'PPB_FileIO_Write', + 'inputs': [['file_io', 'PP_Resource'], + ['offset', 'int64_t'], + ['buffer', 'char[]'], + ['bytes_to_write', 'int32_t'], + ['callback_id', 'int32_t'], + ], + 'outputs': [['pp_error_or_bytes', 'int32_t'], + ] + }, + {'name': 'PPB_FileIO_SetLength', + 'inputs': [['file_io', 'PP_Resource'], + ['length', 'int64_t'], + ['callback_id', 'int32_t'], + ], + 'outputs': [['pp_error', 'int32_t'], + ] + }, + {'name': 'PPB_FileIO_Flush', + 'inputs': [['file_io', 'PP_Resource'], + ['callback_id', 'int32_t'], + ], + 'outputs': [['pp_error', 'int32_t'], + ] + }, + {'name': 'PPB_FileIO_Close', + 'inputs': [['file_io', 'PP_Resource'], + ], + 'outputs': [] + } + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppb_file_ref.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppb_file_ref.srpc new file mode 100644 index 0000000..3775299 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppb_file_ref.srpc @@ -0,0 +1,82 @@ +# 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. + +# RPC methods used to implement PPB_FileIO calls from the plugin. +# See ppapi/c/ppb_file_ref.h for interface details. + +{ + 'name': 'PpbFileRefRpc', + 'rpcs': [ + {'name': 'PPB_FileRef_Create', + 'inputs': [['file_system', 'PP_Resource'], + ['path', 'char[]'], + ], + 'outputs': [['resource', 'PP_Resource'], + ] + }, + {'name': 'PPB_FileRef_IsFileRef', + 'inputs': [['resource', 'PP_Resource'], + ], + 'outputs': [['success', 'int32_t'], # PP_Bool + ] + }, + {'name': 'PPB_FileRef_GetFileSystemType', + 'inputs': [['file_ref', 'PP_Resource'], + ], + 'outputs': [['file_system_type', 'int32_t'], # PP_FileSytemType + ] + }, + {'name': 'PPB_FileRef_GetName', + 'inputs': [['file_ref', 'PP_Resource'], + ], + 'outputs': [['name', 'char[]'], # PP_Var + ] + }, + {'name': 'PPB_FileRef_GetPath', + 'inputs': [['file_ref', 'PP_Resource'], + ], + 'outputs': [['path', 'char[]'], # PP_Var + ] + }, + {'name': 'PPB_FileRef_GetParent', + 'inputs': [['file_ref', 'PP_Resource'], + ], + 'outputs': [['parent', 'PP_Resource'], + ] + }, + {'name': 'PPB_FileRef_MakeDirectory', + 'inputs': [['directory_ref', 'PP_Resource'], + ['make_ancestors', 'int32_t'], # PP_Bool + ['callback_id', 'int32_t'], + ], + 'outputs': [['pp_error', 'int32_t'], + ] + }, + {'name': 'PPB_FileRef_Touch', + 'inputs': [['file_ref', 'PP_Resource'], + ['last_access_time', 'double'], # PP_Time + ['last_modified_time', 'double'], # PP_Time + ['callback_id', 'int32_t'], + ], + 'outputs': [['pp_error', 'int32_t'], + ] + }, + {'name': 'PPB_FileRef_Delete', + 'inputs': [['file_ref', 'PP_Resource'], + ['callback_id', 'int32_t'], + ], + 'outputs': [['pp_error', 'int32_t'], + ] + }, + {'name': 'PPB_FileRef_Rename', + 'inputs': [['file_ref', 'PP_Resource'], + ['new_file_ref', 'PP_Resource'], + ['callback_id', 'int32_t'], + ], + 'outputs': [['pp_error', 'int32_t'], + ] + } + ] +} + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppb_file_system.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppb_file_system.srpc new file mode 100644 index 0000000..266f850 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppb_file_system.srpc @@ -0,0 +1,40 @@ +# 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. + +# RPC methods used to implement PPB_FileSystem calls from the plugin. +# See ppapi/c/ppb_file_system.h for interface details. + +{ + 'name': 'PpbFileSystemRpc', + 'rpcs': [ + {'name': 'PPB_FileSystem_Create', + 'inputs': [['instance', 'PP_Instance'], + ['file_system_type', 'int32_t'], # PP_FileSystemType + ], + 'outputs': [['resource', 'PP_Resource'], + ] + }, + {'name': 'PPB_FileSystem_IsFileSystem', + 'inputs': [['resource', 'PP_Resource'], + ], + 'outputs': [['success', 'int32_t'], # PP_Bool + ] + }, + {'name': 'PPB_FileSystem_Open', + 'inputs': [['file_system', 'PP_Resource'], + ['expected_size', 'int64_t'], + ['callback_id', 'int32_t'] + ], + 'outputs': [['pp_error', 'int32_t'], + ] + }, + {'name': 'PPB_FileSystem_GetType', + 'inputs': [['file_system', 'PP_Resource'], + ], + 'outputs': [['type', 'int32_t'], # PP_FileSystemType + ], + } + ] +} + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppb_find.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppb_find.srpc new file mode 100644 index 0000000..d3077c3 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppb_find.srpc @@ -0,0 +1,26 @@ +# 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. + +# RPC methods used to implement the PPB_Find interface. +# See ppapi/c/dev/ppb_find_dev.h for interface details. +{ + 'name': 'PpbFindRpc', + 'rpcs': [ + {'name': 'PPB_Find_NumberOfFindResultsChanged', + 'inputs': [['instance', 'PP_Instance'], + ['total', 'int32_t'], + ['final_result', 'int32_t'], # PP_Bool + ], + 'outputs': [ + ] + }, + {'name': 'PPB_Find_SelectedFindResultChanged', + 'inputs': [['instance', 'PP_Instance'], + ['index', 'int32_t'], + ], + 'outputs': [ + ] + }, + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppb_font.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppb_font.srpc new file mode 100644 index 0000000..b72bcf1 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppb_font.srpc @@ -0,0 +1,79 @@ +# 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. + +# RPC methods used to implement PPB_Font calls from the plugin. +# See ppapi/c/dev/ppb_font_dev.h for interface details. +{ + 'name': 'PpbFontRpc', + 'rpcs': [ + {'name': 'PPB_Font_GetFontFamilies', + 'inputs': [['instance', 'PP_Instance'], # PP_Instance + ], + 'outputs': [['font_families', 'char[]'], # PP_Var + ] + }, + {'name': 'PPB_Font_Create', + 'inputs': [['instance', 'PP_Instance'], # PP_Instance + ['description', 'char[]'], # PP_FontDescription_Dev + ['face', 'char[]'], # PP_Var, description->face + ], + 'outputs': [['font', 'PP_Resource'], # PP_Resource + ] + }, + {'name': 'PPB_Font_IsFont', + 'inputs': [['resource', 'PP_Resource'], # PP_Resource + ], + 'outputs': [['is_font', 'int32_t'], # PP_Bool + ] + }, + {'name': 'PPB_Font_Describe', + 'inputs': [['font', 'PP_Resource'], # PP_Resource + ], + 'outputs': [['description', 'char[]'], # PP_FontDescription_Dev + ['face', 'char[]'], # PP_Var, description->face + ['metrics', 'char[]'], # PP_FontMetrics_Dev + ['success', 'int32_t'], # PP_Bool + ] + }, + {'name': 'PPB_Font_DrawTextAt', + 'inputs': [['font', 'PP_Resource'], # PP_Resource + ['image_data', 'PP_Resource'], # PP_Resource + ['text_run', 'char[]'], # PP_TextRun_Dev + ['text', 'char[]'], # PP_Var, text_run->text + ['position', 'char[]'], # PP_Point + ['color', 'int32_t'], # uint32_t + ['clip', 'char[]'], # PP_Rect + ['image_data_is_opaque', 'int32_t'], # PP_Bool + ], + 'outputs': [['success', 'int32_t'], # PP_Bool + ] + }, + {'name': 'PPB_Font_MeasureText', + 'inputs': [['font', 'PP_Resource'], # PP_Resource + ['text_run', 'char[]'], # PP_TextRun_Dev + ['text', 'char[]'], # PP_Var, text_run->text + ], + 'outputs': [['width', 'int32_t'], # int32_t + ] + }, + {'name': 'PPB_Font_CharacterOffsetForPixel', + 'inputs': [['font', 'PP_Resource'], # PP_Resource + ['text_run', 'char[]'], # PP_TextRun_Dev + ['text', 'char[]'], # PP_Var, text_run->text + ['pixel_position', 'int32_t'], # int32_t + ], + 'outputs': [['offset', 'int32_t'], # uint32_t + ] + }, + {'name': 'PPB_Font_PixelOffsetForCharacter', + 'inputs': [['font', 'PP_Resource'], # PP_Resource + ['text_run', 'char[]'], # PP_TextRun_Dev + ['text', 'char[]'], # PP_Var, text_run->text + ['char_offset', 'int32_t'], # uint32_t + ], + 'outputs': [['offset', 'int32_t'], # int32_t + ] + }, + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppb_graphics_2d.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppb_graphics_2d.srpc new file mode 100644 index 0000000..a5d9199 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppb_graphics_2d.srpc @@ -0,0 +1,62 @@ +# Copyright (c) 2010 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. +# +# RPC methods used to implement PPB_Graphics2D interface. +# See ppapi/c/ppb_graphics_2d.h for interface details. + +{ + 'name': 'PpbGraphics2DRpc', + 'rpcs': [ + {'name': 'PPB_Graphics2D_Create', + 'inputs': [['instance', 'PP_Instance'], # PP_Instance + ['size', 'char[]'], # PP_Size + ['is_always_opaque', 'int32_t'], # PP_Bool + ], + 'outputs': [['resource', 'PP_Resource'], # PP_Resource + ] + }, + {'name': 'PPB_Graphics2D_IsGraphics2D', + 'inputs': [['resource', 'PP_Resource'], # PP_Resource + ], + 'outputs': [['success', 'int32_t'], # PP_Bool + ] + }, + {'name': 'PPB_Graphics2D_Describe', + 'inputs': [['graphics_2d', 'PP_Resource'], # PP_Resource + ], + 'outputs': [['size', 'char[]'], # PP_Size + ['is_always_opaque', 'int32_t'], # PP_Bool + ['success', 'int32_t'], # PP_Bool + ] + }, + {'name': 'PPB_Graphics2D_PaintImageData', + 'inputs': [['graphics_2d', 'PP_Resource'], # PP_Resource + ['image', 'PP_Resource'], # PP_Resource + ['top_left', 'char[]'], # PP_Point + ['src_rect', 'char[]'], # PP_Rect + ], + 'outputs': [] + }, + {'name': 'PPB_Graphics2D_Scroll', + 'inputs': [['graphics_2d', 'PP_Resource'], # PP_Resource + ['clip_rect', 'char[]'], # PP_Rect + ['amount', 'char[]'], # PP_Point + ], + 'outputs': [] + }, + {'name': 'PPB_Graphics2D_ReplaceContents', + 'inputs': [['graphics_2d', 'PP_Resource'], # PP_Resource + ['image', 'PP_Resource'], # PP_Resource + ], + 'outputs': [] + }, + {'name': 'PPB_Graphics2D_Flush', + 'inputs': [['graphics_2d', 'PP_Resource'], # PP_Resource + ['callback_id', 'int32_t'], # PP_CompletionCallback + ], + 'outputs': [['pp_error', 'int32_t'], # int32_t + ] + }, + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppb_graphics_3d.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppb_graphics_3d.srpc new file mode 100755 index 0000000..797b208 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppb_graphics_3d.srpc @@ -0,0 +1,131 @@ +# 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. + +# This file declares the RPC methods used to implement the Pepper 3D drawing +# API. +# TODO(neb): Figure what the threading model really is. Keep the following +# comment here until then, although it may be wrong: +# All of the following RPC methods are invoked on the NPAPI thread from +# untrusted code. This means, due to the Pepper threading model, that they +# may only be invoked by code that is called from the JavaScript foreground +# thread in the renderer. +{ + 'name': 'PpbGraphics3DRpc', + 'rpcs': [ + # For PPB_Graphics3D.Create(...) + {'name': 'PPB_Graphics3D_Create', + 'inputs': [['instance', 'PP_Instance'], + ['share_context', 'PP_Resource'], + ['attrib_list', 'int32_t[]'] + ], + 'outputs': [['resource_id', 'PP_Resource'] + ], + }, + # For PPB_Graphics3D.GetAttribs(...) + {'name': 'PPB_Graphics3D_GetAttribs', + 'inputs': [['context', 'PP_Resource'], + ['input_attrib_list', 'int32_t[]'] + ], + 'outputs': [['output_attrib_list', 'int32_t[]'], + ['pp_error', 'int32_t'] + ], + }, + # For PPB_Graphics3D.SetAttribs(...) + {'name': 'PPB_Graphics3D_SetAttribs', + 'inputs': [['context', 'PP_Resource'], + ['attrib_list', 'int32_t[]'] + ], + 'outputs': [['pp_error', 'int32_t'] + ], + }, + # For PPB_Graphics3D.ResizeBuffers(...) + {'name': 'PPB_Graphics3D_ResizeBuffers', + 'inputs': [['context', 'PP_Resource'], + ['width', 'int32_t'], + ['height', 'int32_t'] + ], + 'outputs': [['pp_error', 'int32_t'] + ], + }, + # For PPB_Graphics3D.SwapBuffers(...) + {'name': 'PPB_Graphics3D_SwapBuffers', + 'inputs': [['context', 'PP_Resource'], + ['callback_id', 'int32_t'] + ], + 'outputs': [['pp_error', 'int32_t'] + ], + }, + # End of PPB_Graphics3D. + + # Start of PPB_Graphics3DTrusted. + # Create a Graphics3D context. + {'name': 'PPB_Graphics3DTrusted_CreateRaw', + 'inputs': [['instance', 'PP_Instance'], + ['share_context', 'PP_Resource'], + ['attrib_list', 'int32_t[]'] + ], + 'outputs': [['resource_id', 'PP_Resource']] + }, + # Initialize the command buffer. + {'name': 'PPB_Graphics3DTrusted_InitCommandBuffer', + 'inputs': [['resource_id', 'PP_Resource'], + ['size', 'int32_t'] + ], + 'outputs': [['success', 'int32_t']] # PP_Bool + }, + # Get the ring buffer. + {'name': 'PPB_Graphics3DTrusted_GetRingBuffer', + 'inputs': [['resource_id', 'PP_Resource']], + 'outputs': [['shm_desc', 'handle'], + ['shm_size', 'int32_t'] + ] + }, + # Get command buffer state. + {'name': 'PPB_Graphics3DTrusted_GetState', + 'inputs': [['resource_id', 'PP_Resource']], + 'outputs': [['state', 'char[]'], # PP_Graphics3DTrustedState + ] + }, + # Flush async. + {'name': 'PPB_Graphics3DTrusted_Flush', + 'inputs': [['resource_id', 'PP_Resource'], + ['put_offset', 'int32_t'] + ], + 'outputs': [] + }, + # Flush sync. + {'name': 'PPB_Graphics3DTrusted_FlushSync', + 'inputs': [['resource_id', 'PP_Resource'], + ['put_offset', 'int32_t'] + ], + 'outputs': [['state', 'char[]'], # PP_Graphics3DTrustedState + ] + }, + # Create a shared memory transfer buffer. + {'name': 'PPB_Graphics3DTrusted_CreateTransferBuffer', + 'inputs': [['resource_id', 'PP_Resource'], + ['size', 'int32_t'], + ['request_id', 'int32_t'] + ], + 'outputs': [['id', 'int32_t']] + }, + # Destroy a shared memory transfer buffer. + {'name': 'PPB_Graphics3DTrusted_DestroyTransferBuffer', + 'inputs': [['resource_id', 'PP_Resource'], + ['id', 'int32_t'], + ], + 'outputs': [] + }, + # Get a shared memory transfer buffer. + {'name': 'PPB_Graphics3DTrusted_GetTransferBuffer', + 'inputs': [['resource_id', 'PP_Resource'], + ['id', 'int32_t'], + ], + 'outputs': [['shm_desc', 'handle'], + ['shm_size', 'int32_t'] + ] + }, + # End of PPB_Graphics3DTrusted + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppb_image_data.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppb_image_data.srpc new file mode 100644 index 0000000..ba2376a --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppb_image_data.srpc @@ -0,0 +1,46 @@ +# Copyright (c) 2010 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. + +# This file declares the RPC methods used to implement PPB_ImageData calls from +# the plugin. The functions are described in ppapi/c/ppb_image_data.h. +{ + 'name': 'PpbImageDataRpc', + 'rpcs': [ + {'name': 'PPB_ImageData_GetNativeImageDataFormat', + 'inputs': [], + 'outputs': [['format', 'int32_t'], + ] + }, + {'name': 'PPB_ImageData_IsImageDataFormatSupported', + 'inputs': [['format', 'int32_t'], + ], + 'outputs': [['success', 'int32_t'], + ] + }, + {'name': 'PPB_ImageData_Create', + 'inputs': [['instance', 'PP_Instance'], + ['format', 'int32_t'], + ['size', 'char[]'], # PP_Size + ['init_to_zero', 'int32_t'], + ], + 'outputs': [['resource', 'PP_Resource'], + ] + }, + {'name': 'PPB_ImageData_IsImageData', + 'inputs': [['resource', 'PP_Resource'], + ], + 'outputs': [['success', 'int32_t'], + ] + }, + {'name': 'PPB_ImageData_Describe', + 'inputs': [['resource', 'PP_Resource'], + ], + 'outputs': [['desc', 'char[]'], # PP_ImageDataDesc + ['shm', 'handle'], + ['shm_size', 'int32_t'], + ['success', 'int32_t'], + ] + }, + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppb_input_event.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppb_input_event.srpc new file mode 100644 index 0000000..cb28783c --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppb_input_event.srpc @@ -0,0 +1,61 @@ +# 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. + +# RPC methods used to implement the PPB_InputEvent interface. +# See ppapi/c/ppb_input_event.h for interface details. +{ + 'name': 'PpbInputEventRpc', + 'rpcs': [ + {'name': 'PPB_InputEvent_RequestInputEvents', + 'inputs': [['instance', 'PP_Instance'], # PP_Instance + ['event_classes', 'int32_t'], # uint32_t, bitfield + ['filtered', 'int32_t'] # bool + ], + 'outputs': [['success', 'int32_t'], # pp_error value + ] + }, + {'name': 'PPB_InputEvent_ClearInputEventRequest', + 'inputs': [['instance', 'PP_Instance'], # PP_Instance + ['event_classes', 'int32_t'] # uint32_t, bitfield + ], + 'outputs': [] + }, + {'name': 'PPB_InputEvent_CreateMouseInputEvent', + 'inputs': [['instance', 'PP_Instance'], # PP_Instance + ['type', 'int32_t'], # PP_InputEvent_Type + ['time_stamp', 'double'], # PP_TimeTicks + ['modifiers', 'int32_t'], # uint32_t + ['mouse_button', 'int32_t'], # PP_InputEvent_MouseButton + ['mouse_position_x', 'int32_t'], # PP_Point.x + ['mouse_position_y', 'int32_t'], # PP_Point.y + ['click_count', 'int32_t'] + ], + 'outputs': [['resource_id', 'PP_Resource']] + }, + {'name': 'PPB_InputEvent_CreateWheelInputEvent', + 'inputs': [['instance', 'PP_Instance'], # PP_Instance + ['time_stamp', 'double'], # PP_TimeTicks + ['modifiers', 'int32_t'], # uint32_t + ['wheel_delta_x', 'double'], # PP_FloatPoint.x + ['wheel_delta_y', 'double'], # PP_FloatPoint.y + ['wheel_ticks_x', 'double'], # PP_FloatPoint.x + ['wheel_ticks_y', 'double'], # PP_FloatPoint.y + ['scroll_by_page', 'int32_t'] # PP_Bool + ], + 'outputs': [['resource_id', 'PP_Resource']] + }, + {'name': 'PPB_InputEvent_CreateKeyboardInputEvent', + 'inputs': [['instance', 'PP_Instance'], # PP_Instance + ['type', 'int32_t'], # PP_InputEvent_Type + ['time_stamp', 'double'], # PP_TimeTicks + ['modifiers', 'int32_t'], # uint32_t + ['key_code', 'int32_t'], # uint32_t + ['character_text', 'char[]'] # String PP_Var + ], + 'outputs': [['resource_id', 'PP_Resource']] + } + + ] +} + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppb_instance.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppb_instance.srpc new file mode 100644 index 0000000..ba0e8eb --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppb_instance.srpc @@ -0,0 +1,24 @@ +# Copyright (c) 2010 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. + +# RPC methods used to implement PPB_Instance interface. +# See ppapi/c/ppb_instance.h for interface details. +{ + 'name': 'PpbInstanceRpc', + 'rpcs': [ + {'name': 'PPB_Instance_BindGraphics', + 'inputs': [['instance', 'PP_Instance'], # PP_Instance + ['graphics_device', 'PP_Resource'], # PP_Resource + ], + 'outputs': [['success', 'int32_t'], # PP_Bool + ] + }, + {'name': 'PPB_Instance_IsFullFrame', + 'inputs': [['instance', 'PP_Instance'], # PP_Instance + ], + 'outputs': [['is_full_frame', 'int32_t'], # PP_Bool + ] + }, + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppb_messaging.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppb_messaging.srpc new file mode 100644 index 0000000..03333b6 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppb_messaging.srpc @@ -0,0 +1,17 @@ +# 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. + +# RPC methods used to implement PPB_Messaging interface. +# See ppapi/c/ppb_messaging.h for interface details. +{ + 'name': 'PpbMessagingRpc', + 'rpcs': [ + {'name': 'PPB_Messaging_PostMessage', + 'inputs': [['instance', 'PP_Instance'], # PP_Instance + ['message', 'char[]'], # PP_Var + ], + 'outputs': [] + }, + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppb_pdf.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppb_pdf.srpc new file mode 100644 index 0000000..400a367 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppb_pdf.srpc @@ -0,0 +1,95 @@ +# 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. + +# RPC methods used to implement the PPB_PDF interface. +# See ppapi/c/private/ppb_pdf.h for interface details. +{ + 'name': 'PpbPdfRpc', + 'rpcs': [ + {'name': 'PPB_PDF_GetLocalizedString', + 'inputs': [['instance', 'PP_Instance'], + ['string_id', 'int32_t'], # PP_ResourceString + ], + 'outputs': [['string', 'char[]'], # PP_Var + ] + }, + {'name': 'PPB_PDF_GetResourceImage', + 'inputs': [['instance', 'PP_Instance'], + ['image_id', 'int32_t'], # PP_ResourceImage + ], + 'outputs': [['image', 'PP_Resource'], + ] + }, + {'name': 'PPB_PDF_GetFontFileWithFallback', + 'inputs': [['instance', 'PP_Instance'], + ['description', 'char[]'], # PP_FontDescription_Dev + ['face', 'char[]'], # PP_Var, description->face + ['charset', 'int32_t'], # PP_PrivateFontCharset + ], + 'outputs': [['font', 'PP_Resource'], + ] + }, + {'name': 'PPB_PDF_GetFontTableForPrivateFontFile', + 'inputs': [['font_file', 'PP_Resource'], + ['table', 'int32_t'], # uint32_t + ], + 'outputs': [['output', 'char[]'], # void*, uint32_t* + ['success', 'int32_t'], # PP_Bool + ] + }, + {'name': 'PPB_PDF_SearchString', + 'inputs': [['instance', 'PP_Instance'], + ['string', 'char[]'], # const unsigned short* + ['term', 'char[]'], # const unsigned short* + ['case_sensitive', 'int32_t'], # bool + ], + 'outputs': [['results', 'char[]'], # PP_PrivateFindResult** + ['count', 'int32_t'], # int* + ] + }, + {'name': 'PPB_PDF_DidStartLoading', + 'inputs': [['instance', 'PP_Instance'], + ], + 'outputs': [ + ] + }, + {'name': 'PPB_PDF_DidStopLoading', + 'inputs': [['instance', 'PP_Instance'], + ], + 'outputs': [ + ] + }, + {'name': 'PPB_PDF_SetContentRestriction', + 'inputs': [['instance', 'PP_Instance'], + ['restrictions', 'int32_t'], # int + ], + 'outputs': [ + ] + }, + {'name': 'PPB_PDF_HistogramPDFPageCount', + 'inputs': [['count', 'int32_t'], + ], + 'outputs': [ + ] + }, + {'name': 'PPB_PDF_UserMetricsRecordAction', + 'inputs': [['action', 'char[]'], # PP_Var + ], + 'outputs': [ + ] + }, + {'name': 'PPB_PDF_HasUnsupportedFeature', + 'inputs': [['instance', 'PP_Instance'], # PP_Instance + ], + 'outputs': [ + ] + }, + {'name': 'PPB_PDF_SaveAs', + 'inputs': [['instance', 'PP_Instance'], # PP_Instance + ], + 'outputs': [ + ] + }, + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppb_rpc_client.cc b/ppapi/native_client/src/shared/ppapi_proxy/ppb_rpc_client.cc new file mode 100644 index 0000000..1481c1f --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppb_rpc_client.cc @@ -0,0 +1,2717 @@ +// 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. +// +// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING +// +// Automatically generated code. See srpcgen.py +// +// NaCl Simple Remote Procedure Call interface abstractions. + +#include "untrusted/srpcgen/ppb_rpc.h" +#ifdef __native_client__ +#ifndef UNREFERENCED_PARAMETER +#define UNREFERENCED_PARAMETER(P) do { (void) P; } while (0) +#endif // UNREFERENCED_PARAMETER +#else +#include "native_client/src/include/portability.h" +#endif // __native_client__ +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/ppb_core.h" + +NaClSrpcError NaClFileRpcClient::StreamAsFile( + NaClSrpcChannel* channel, + PP_Instance instance, + char* url, + int32_t callback_id) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "StreamAsFile:isi:", + instance, + url, + callback_id + ); + return retval; +} + +NaClSrpcError NaClFileRpcClient::GetFileDesc( + NaClSrpcChannel* channel, + PP_Instance instance, + char* url, + NaClSrpcImcDescType* file_desc) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "GetFileDesc:is:h", + instance, + url, + file_desc + ); + return retval; +} + +NaClSrpcError PpbRpcClient::PPB_GetInterface( + NaClSrpcChannel* channel, + char* interface_name, + int32_t* exports_interface_name) { + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_GetInterface:s:i", + interface_name, + exports_interface_name + ); + return retval; +} + +NaClSrpcError PpbAudioRpcClient::PPB_Audio_Create( + NaClSrpcChannel* channel, + PP_Instance instance, + PP_Resource config, + PP_Resource* out_resource) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Audio_Create:ii:i", + instance, + config, + out_resource + ); + return retval; +} + +NaClSrpcError PpbAudioRpcClient::PPB_Audio_IsAudio( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* out_bool) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Audio_IsAudio:i:i", + resource, + out_bool + ); + return retval; +} + +NaClSrpcError PpbAudioRpcClient::PPB_Audio_GetCurrentConfig( + NaClSrpcChannel* channel, + PP_Resource resource, + PP_Resource* out_resource) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Audio_GetCurrentConfig:i:i", + resource, + out_resource + ); + return retval; +} + +NaClSrpcError PpbAudioRpcClient::PPB_Audio_StopPlayback( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* out_bool) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Audio_StopPlayback:i:i", + resource, + out_bool + ); + return retval; +} + +NaClSrpcError PpbAudioRpcClient::PPB_Audio_StartPlayback( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* out_bool) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Audio_StartPlayback:i:i", + resource, + out_bool + ); + return retval; +} + +NaClSrpcError PpbAudioConfigRpcClient::PPB_AudioConfig_CreateStereo16Bit( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t sample_rate, + int32_t sample_frame_count, + PP_Resource* resource) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_AudioConfig_CreateStereo16Bit:iii:i", + instance, + sample_rate, + sample_frame_count, + resource + ); + return retval; +} + +NaClSrpcError PpbAudioConfigRpcClient::PPB_AudioConfig_IsAudioConfig( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* out_bool) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_AudioConfig_IsAudioConfig:i:i", + resource, + out_bool + ); + return retval; +} + +NaClSrpcError PpbAudioConfigRpcClient::PPB_AudioConfig_RecommendSampleFrameCount( + NaClSrpcChannel* channel, + int32_t request_sample_rate, + int32_t request_sample_frame_count, + int32_t* out_sample_frame_count) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_AudioConfig_RecommendSampleFrameCount:ii:i", + request_sample_rate, + request_sample_frame_count, + out_sample_frame_count + ); + return retval; +} + +NaClSrpcError PpbAudioConfigRpcClient::PPB_AudioConfig_GetSampleRate( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* sample_rate) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_AudioConfig_GetSampleRate:i:i", + resource, + sample_rate + ); + return retval; +} + +NaClSrpcError PpbAudioConfigRpcClient::PPB_AudioConfig_GetSampleFrameCount( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* sample_frame_count) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_AudioConfig_GetSampleFrameCount:i:i", + resource, + sample_frame_count + ); + return retval; +} + +NaClSrpcError PpbCoreRpcClient::PPB_Core_AddRefResource( + NaClSrpcChannel* channel, + PP_Resource resource) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Core_AddRefResource:i:", + resource + ); + return retval; +} + +NaClSrpcError PpbCoreRpcClient::PPB_Core_ReleaseResource( + NaClSrpcChannel* channel, + PP_Resource resource) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Core_ReleaseResource:i:", + resource + ); + return retval; +} + +NaClSrpcError PpbCoreRpcClient::ReleaseResourceMultipleTimes( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t count) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "ReleaseResourceMultipleTimes:ii:", + resource, + count + ); + return retval; +} + +NaClSrpcError PpbCoreRpcClient::PPB_Core_GetTime( + NaClSrpcChannel* channel, + double* time) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Core_GetTime::d", + time + ); + return retval; +} + +NaClSrpcError PpbCoreRpcClient::PPB_Core_GetTimeTicks( + NaClSrpcChannel* channel, + double* time_ticks) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Core_GetTimeTicks::d", + time_ticks + ); + return retval; +} + +NaClSrpcError PpbCoreRpcClient::PPB_Core_CallOnMainThread( + NaClSrpcChannel* channel, + int32_t delay_in_milliseconds, + int32_t callback_id, + int32_t result) { + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Core_CallOnMainThread:iii:", + delay_in_milliseconds, + callback_id, + result + ); + return retval; +} + +NaClSrpcError PpbCursorControlRpcClient::PPB_CursorControl_SetCursor( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t type, + PP_Resource custom_image, + nacl_abi_size_t hot_spot_bytes, char* hot_spot, + int32_t* success) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_CursorControl_SetCursor:iiiC:i", + instance, + type, + custom_image, + hot_spot_bytes, hot_spot, + success + ); + return retval; +} + +NaClSrpcError PpbCursorControlRpcClient::PPB_CursorControl_LockCursor( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t* success) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_CursorControl_LockCursor:i:i", + instance, + success + ); + return retval; +} + +NaClSrpcError PpbCursorControlRpcClient::PPB_CursorControl_UnlockCursor( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t* success) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_CursorControl_UnlockCursor:i:i", + instance, + success + ); + return retval; +} + +NaClSrpcError PpbCursorControlRpcClient::PPB_CursorControl_HasCursorLock( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t* success) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_CursorControl_HasCursorLock:i:i", + instance, + success + ); + return retval; +} + +NaClSrpcError PpbCursorControlRpcClient::PPB_CursorControl_CanLockCursor( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t* success) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_CursorControl_CanLockCursor:i:i", + instance, + success + ); + return retval; +} + +NaClSrpcError PpbFileIORpcClient::PPB_FileIO_Create( + NaClSrpcChannel* channel, + PP_Instance instance, + PP_Resource* resource) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_FileIO_Create:i:i", + instance, + resource + ); + return retval; +} + +NaClSrpcError PpbFileIORpcClient::PPB_FileIO_IsFileIO( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* success) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_FileIO_IsFileIO:i:i", + resource, + success + ); + return retval; +} + +NaClSrpcError PpbFileIORpcClient::PPB_FileIO_Open( + NaClSrpcChannel* channel, + PP_Resource file_io, + PP_Resource file_ref, + int32_t open_flags, + int32_t callback_id, + int32_t* pp_error) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_FileIO_Open:iiii:i", + file_io, + file_ref, + open_flags, + callback_id, + pp_error + ); + return retval; +} + +NaClSrpcError PpbFileIORpcClient::PPB_FileIO_Query( + NaClSrpcChannel* channel, + PP_Resource file_io, + int32_t bytes_to_read, + int32_t callback_id, + nacl_abi_size_t* info_bytes, char* info, + int32_t* pp_error) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_FileIO_Query:iii:Ci", + file_io, + bytes_to_read, + callback_id, + info_bytes, info, + pp_error + ); + return retval; +} + +NaClSrpcError PpbFileIORpcClient::PPB_FileIO_Touch( + NaClSrpcChannel* channel, + PP_Resource file_io, + double last_access_time, + double last_modified_time, + int32_t callback_id, + int32_t* pp_error) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_FileIO_Touch:iddi:i", + file_io, + last_access_time, + last_modified_time, + callback_id, + pp_error + ); + return retval; +} + +NaClSrpcError PpbFileIORpcClient::PPB_FileIO_Read( + NaClSrpcChannel* channel, + PP_Resource file_io, + int64_t offset, + int32_t bytes_to_read, + int32_t callback_id, + nacl_abi_size_t* buffer_bytes, char* buffer, + int32_t* pp_error_or_bytes) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_FileIO_Read:ilii:Ci", + file_io, + offset, + bytes_to_read, + callback_id, + buffer_bytes, buffer, + pp_error_or_bytes + ); + return retval; +} + +NaClSrpcError PpbFileIORpcClient::PPB_FileIO_Write( + NaClSrpcChannel* channel, + PP_Resource file_io, + int64_t offset, + nacl_abi_size_t buffer_bytes, char* buffer, + int32_t bytes_to_write, + int32_t callback_id, + int32_t* pp_error_or_bytes) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_FileIO_Write:ilCii:i", + file_io, + offset, + buffer_bytes, buffer, + bytes_to_write, + callback_id, + pp_error_or_bytes + ); + return retval; +} + +NaClSrpcError PpbFileIORpcClient::PPB_FileIO_SetLength( + NaClSrpcChannel* channel, + PP_Resource file_io, + int64_t length, + int32_t callback_id, + int32_t* pp_error) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_FileIO_SetLength:ili:i", + file_io, + length, + callback_id, + pp_error + ); + return retval; +} + +NaClSrpcError PpbFileIORpcClient::PPB_FileIO_Flush( + NaClSrpcChannel* channel, + PP_Resource file_io, + int32_t callback_id, + int32_t* pp_error) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_FileIO_Flush:ii:i", + file_io, + callback_id, + pp_error + ); + return retval; +} + +NaClSrpcError PpbFileIORpcClient::PPB_FileIO_Close( + NaClSrpcChannel* channel, + PP_Resource file_io) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_FileIO_Close:i:", + file_io + ); + return retval; +} + +NaClSrpcError PpbFileRefRpcClient::PPB_FileRef_Create( + NaClSrpcChannel* channel, + PP_Resource file_system, + nacl_abi_size_t path_bytes, char* path, + PP_Resource* resource) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_FileRef_Create:iC:i", + file_system, + path_bytes, path, + resource + ); + return retval; +} + +NaClSrpcError PpbFileRefRpcClient::PPB_FileRef_IsFileRef( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* success) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_FileRef_IsFileRef:i:i", + resource, + success + ); + return retval; +} + +NaClSrpcError PpbFileRefRpcClient::PPB_FileRef_GetFileSystemType( + NaClSrpcChannel* channel, + PP_Resource file_ref, + int32_t* file_system_type) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_FileRef_GetFileSystemType:i:i", + file_ref, + file_system_type + ); + return retval; +} + +NaClSrpcError PpbFileRefRpcClient::PPB_FileRef_GetName( + NaClSrpcChannel* channel, + PP_Resource file_ref, + nacl_abi_size_t* name_bytes, char* name) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_FileRef_GetName:i:C", + file_ref, + name_bytes, name + ); + return retval; +} + +NaClSrpcError PpbFileRefRpcClient::PPB_FileRef_GetPath( + NaClSrpcChannel* channel, + PP_Resource file_ref, + nacl_abi_size_t* path_bytes, char* path) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_FileRef_GetPath:i:C", + file_ref, + path_bytes, path + ); + return retval; +} + +NaClSrpcError PpbFileRefRpcClient::PPB_FileRef_GetParent( + NaClSrpcChannel* channel, + PP_Resource file_ref, + PP_Resource* parent) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_FileRef_GetParent:i:i", + file_ref, + parent + ); + return retval; +} + +NaClSrpcError PpbFileRefRpcClient::PPB_FileRef_MakeDirectory( + NaClSrpcChannel* channel, + PP_Resource directory_ref, + int32_t make_ancestors, + int32_t callback_id, + int32_t* pp_error) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_FileRef_MakeDirectory:iii:i", + directory_ref, + make_ancestors, + callback_id, + pp_error + ); + return retval; +} + +NaClSrpcError PpbFileRefRpcClient::PPB_FileRef_Touch( + NaClSrpcChannel* channel, + PP_Resource file_ref, + double last_access_time, + double last_modified_time, + int32_t callback_id, + int32_t* pp_error) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_FileRef_Touch:iddi:i", + file_ref, + last_access_time, + last_modified_time, + callback_id, + pp_error + ); + return retval; +} + +NaClSrpcError PpbFileRefRpcClient::PPB_FileRef_Delete( + NaClSrpcChannel* channel, + PP_Resource file_ref, + int32_t callback_id, + int32_t* pp_error) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_FileRef_Delete:ii:i", + file_ref, + callback_id, + pp_error + ); + return retval; +} + +NaClSrpcError PpbFileRefRpcClient::PPB_FileRef_Rename( + NaClSrpcChannel* channel, + PP_Resource file_ref, + PP_Resource new_file_ref, + int32_t callback_id, + int32_t* pp_error) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_FileRef_Rename:iii:i", + file_ref, + new_file_ref, + callback_id, + pp_error + ); + return retval; +} + +NaClSrpcError PpbFileSystemRpcClient::PPB_FileSystem_Create( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t file_system_type, + PP_Resource* resource) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_FileSystem_Create:ii:i", + instance, + file_system_type, + resource + ); + return retval; +} + +NaClSrpcError PpbFileSystemRpcClient::PPB_FileSystem_IsFileSystem( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* success) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_FileSystem_IsFileSystem:i:i", + resource, + success + ); + return retval; +} + +NaClSrpcError PpbFileSystemRpcClient::PPB_FileSystem_Open( + NaClSrpcChannel* channel, + PP_Resource file_system, + int64_t expected_size, + int32_t callback_id, + int32_t* pp_error) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_FileSystem_Open:ili:i", + file_system, + expected_size, + callback_id, + pp_error + ); + return retval; +} + +NaClSrpcError PpbFileSystemRpcClient::PPB_FileSystem_GetType( + NaClSrpcChannel* channel, + PP_Resource file_system, + int32_t* type) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_FileSystem_GetType:i:i", + file_system, + type + ); + return retval; +} + +NaClSrpcError PpbFindRpcClient::PPB_Find_NumberOfFindResultsChanged( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t total, + int32_t final_result) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Find_NumberOfFindResultsChanged:iii:", + instance, + total, + final_result + ); + return retval; +} + +NaClSrpcError PpbFindRpcClient::PPB_Find_SelectedFindResultChanged( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t index) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Find_SelectedFindResultChanged:ii:", + instance, + index + ); + return retval; +} + +NaClSrpcError PpbFontRpcClient::PPB_Font_GetFontFamilies( + NaClSrpcChannel* channel, + PP_Instance instance, + nacl_abi_size_t* font_families_bytes, char* font_families) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Font_GetFontFamilies:i:C", + instance, + font_families_bytes, font_families + ); + return retval; +} + +NaClSrpcError PpbFontRpcClient::PPB_Font_Create( + NaClSrpcChannel* channel, + PP_Instance instance, + nacl_abi_size_t description_bytes, char* description, + nacl_abi_size_t face_bytes, char* face, + PP_Resource* font) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Font_Create:iCC:i", + instance, + description_bytes, description, + face_bytes, face, + font + ); + return retval; +} + +NaClSrpcError PpbFontRpcClient::PPB_Font_IsFont( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* is_font) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Font_IsFont:i:i", + resource, + is_font + ); + return retval; +} + +NaClSrpcError PpbFontRpcClient::PPB_Font_Describe( + NaClSrpcChannel* channel, + PP_Resource font, + nacl_abi_size_t* description_bytes, char* description, + nacl_abi_size_t* face_bytes, char* face, + nacl_abi_size_t* metrics_bytes, char* metrics, + int32_t* success) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Font_Describe:i:CCCi", + font, + description_bytes, description, + face_bytes, face, + metrics_bytes, metrics, + success + ); + return retval; +} + +NaClSrpcError PpbFontRpcClient::PPB_Font_DrawTextAt( + NaClSrpcChannel* channel, + PP_Resource font, + PP_Resource image_data, + nacl_abi_size_t text_run_bytes, char* text_run, + nacl_abi_size_t text_bytes, char* text, + nacl_abi_size_t position_bytes, char* position, + int32_t color, + nacl_abi_size_t clip_bytes, char* clip, + int32_t image_data_is_opaque, + int32_t* success) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Font_DrawTextAt:iiCCCiCi:i", + font, + image_data, + text_run_bytes, text_run, + text_bytes, text, + position_bytes, position, + color, + clip_bytes, clip, + image_data_is_opaque, + success + ); + return retval; +} + +NaClSrpcError PpbFontRpcClient::PPB_Font_MeasureText( + NaClSrpcChannel* channel, + PP_Resource font, + nacl_abi_size_t text_run_bytes, char* text_run, + nacl_abi_size_t text_bytes, char* text, + int32_t* width) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Font_MeasureText:iCC:i", + font, + text_run_bytes, text_run, + text_bytes, text, + width + ); + return retval; +} + +NaClSrpcError PpbFontRpcClient::PPB_Font_CharacterOffsetForPixel( + NaClSrpcChannel* channel, + PP_Resource font, + nacl_abi_size_t text_run_bytes, char* text_run, + nacl_abi_size_t text_bytes, char* text, + int32_t pixel_position, + int32_t* offset) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Font_CharacterOffsetForPixel:iCCi:i", + font, + text_run_bytes, text_run, + text_bytes, text, + pixel_position, + offset + ); + return retval; +} + +NaClSrpcError PpbFontRpcClient::PPB_Font_PixelOffsetForCharacter( + NaClSrpcChannel* channel, + PP_Resource font, + nacl_abi_size_t text_run_bytes, char* text_run, + nacl_abi_size_t text_bytes, char* text, + int32_t char_offset, + int32_t* offset) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Font_PixelOffsetForCharacter:iCCi:i", + font, + text_run_bytes, text_run, + text_bytes, text, + char_offset, + offset + ); + return retval; +} + +NaClSrpcError PpbGraphics2DRpcClient::PPB_Graphics2D_Create( + NaClSrpcChannel* channel, + PP_Instance instance, + nacl_abi_size_t size_bytes, char* size, + int32_t is_always_opaque, + PP_Resource* resource) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Graphics2D_Create:iCi:i", + instance, + size_bytes, size, + is_always_opaque, + resource + ); + return retval; +} + +NaClSrpcError PpbGraphics2DRpcClient::PPB_Graphics2D_IsGraphics2D( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* success) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Graphics2D_IsGraphics2D:i:i", + resource, + success + ); + return retval; +} + +NaClSrpcError PpbGraphics2DRpcClient::PPB_Graphics2D_Describe( + NaClSrpcChannel* channel, + PP_Resource graphics_2d, + nacl_abi_size_t* size_bytes, char* size, + int32_t* is_always_opaque, + int32_t* success) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Graphics2D_Describe:i:Cii", + graphics_2d, + size_bytes, size, + is_always_opaque, + success + ); + return retval; +} + +NaClSrpcError PpbGraphics2DRpcClient::PPB_Graphics2D_PaintImageData( + NaClSrpcChannel* channel, + PP_Resource graphics_2d, + PP_Resource image, + nacl_abi_size_t top_left_bytes, char* top_left, + nacl_abi_size_t src_rect_bytes, char* src_rect) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Graphics2D_PaintImageData:iiCC:", + graphics_2d, + image, + top_left_bytes, top_left, + src_rect_bytes, src_rect + ); + return retval; +} + +NaClSrpcError PpbGraphics2DRpcClient::PPB_Graphics2D_Scroll( + NaClSrpcChannel* channel, + PP_Resource graphics_2d, + nacl_abi_size_t clip_rect_bytes, char* clip_rect, + nacl_abi_size_t amount_bytes, char* amount) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Graphics2D_Scroll:iCC:", + graphics_2d, + clip_rect_bytes, clip_rect, + amount_bytes, amount + ); + return retval; +} + +NaClSrpcError PpbGraphics2DRpcClient::PPB_Graphics2D_ReplaceContents( + NaClSrpcChannel* channel, + PP_Resource graphics_2d, + PP_Resource image) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Graphics2D_ReplaceContents:ii:", + graphics_2d, + image + ); + return retval; +} + +NaClSrpcError PpbGraphics2DRpcClient::PPB_Graphics2D_Flush( + NaClSrpcChannel* channel, + PP_Resource graphics_2d, + int32_t callback_id, + int32_t* pp_error) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Graphics2D_Flush:ii:i", + graphics_2d, + callback_id, + pp_error + ); + return retval; +} + +NaClSrpcError PpbGraphics3DRpcClient::PPB_Graphics3D_Create( + NaClSrpcChannel* channel, + PP_Instance instance, + PP_Resource share_context, + nacl_abi_size_t attrib_list_bytes, int32_t* attrib_list, + PP_Resource* resource_id) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Graphics3D_Create:iiI:i", + instance, + share_context, + attrib_list_bytes, attrib_list, + resource_id + ); + return retval; +} + +NaClSrpcError PpbGraphics3DRpcClient::PPB_Graphics3D_GetAttribs( + NaClSrpcChannel* channel, + PP_Resource context, + nacl_abi_size_t input_attrib_list_bytes, int32_t* input_attrib_list, + nacl_abi_size_t* output_attrib_list_bytes, int32_t* output_attrib_list, + int32_t* pp_error) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Graphics3D_GetAttribs:iI:Ii", + context, + input_attrib_list_bytes, input_attrib_list, + output_attrib_list_bytes, output_attrib_list, + pp_error + ); + return retval; +} + +NaClSrpcError PpbGraphics3DRpcClient::PPB_Graphics3D_SetAttribs( + NaClSrpcChannel* channel, + PP_Resource context, + nacl_abi_size_t attrib_list_bytes, int32_t* attrib_list, + int32_t* pp_error) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Graphics3D_SetAttribs:iI:i", + context, + attrib_list_bytes, attrib_list, + pp_error + ); + return retval; +} + +NaClSrpcError PpbGraphics3DRpcClient::PPB_Graphics3D_ResizeBuffers( + NaClSrpcChannel* channel, + PP_Resource context, + int32_t width, + int32_t height, + int32_t* pp_error) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Graphics3D_ResizeBuffers:iii:i", + context, + width, + height, + pp_error + ); + return retval; +} + +NaClSrpcError PpbGraphics3DRpcClient::PPB_Graphics3D_SwapBuffers( + NaClSrpcChannel* channel, + PP_Resource context, + int32_t callback_id, + int32_t* pp_error) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Graphics3D_SwapBuffers:ii:i", + context, + callback_id, + pp_error + ); + return retval; +} + +NaClSrpcError PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_CreateRaw( + NaClSrpcChannel* channel, + PP_Instance instance, + PP_Resource share_context, + nacl_abi_size_t attrib_list_bytes, int32_t* attrib_list, + PP_Resource* resource_id) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Graphics3DTrusted_CreateRaw:iiI:i", + instance, + share_context, + attrib_list_bytes, attrib_list, + resource_id + ); + return retval; +} + +NaClSrpcError PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_InitCommandBuffer( + NaClSrpcChannel* channel, + PP_Resource resource_id, + int32_t size, + int32_t* success) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Graphics3DTrusted_InitCommandBuffer:ii:i", + resource_id, + size, + success + ); + return retval; +} + +NaClSrpcError PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_GetRingBuffer( + NaClSrpcChannel* channel, + PP_Resource resource_id, + NaClSrpcImcDescType* shm_desc, + int32_t* shm_size) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Graphics3DTrusted_GetRingBuffer:i:hi", + resource_id, + shm_desc, + shm_size + ); + return retval; +} + +NaClSrpcError PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_GetState( + NaClSrpcChannel* channel, + PP_Resource resource_id, + nacl_abi_size_t* state_bytes, char* state) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Graphics3DTrusted_GetState:i:C", + resource_id, + state_bytes, state + ); + return retval; +} + +NaClSrpcError PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_Flush( + NaClSrpcChannel* channel, + PP_Resource resource_id, + int32_t put_offset) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Graphics3DTrusted_Flush:ii:", + resource_id, + put_offset + ); + return retval; +} + +NaClSrpcError PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_FlushSync( + NaClSrpcChannel* channel, + PP_Resource resource_id, + int32_t put_offset, + nacl_abi_size_t* state_bytes, char* state) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Graphics3DTrusted_FlushSync:ii:C", + resource_id, + put_offset, + state_bytes, state + ); + return retval; +} + +NaClSrpcError PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_CreateTransferBuffer( + NaClSrpcChannel* channel, + PP_Resource resource_id, + int32_t size, + int32_t request_id, + int32_t* id) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Graphics3DTrusted_CreateTransferBuffer:iii:i", + resource_id, + size, + request_id, + id + ); + return retval; +} + +NaClSrpcError PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_DestroyTransferBuffer( + NaClSrpcChannel* channel, + PP_Resource resource_id, + int32_t id) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Graphics3DTrusted_DestroyTransferBuffer:ii:", + resource_id, + id + ); + return retval; +} + +NaClSrpcError PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_GetTransferBuffer( + NaClSrpcChannel* channel, + PP_Resource resource_id, + int32_t id, + NaClSrpcImcDescType* shm_desc, + int32_t* shm_size) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Graphics3DTrusted_GetTransferBuffer:ii:hi", + resource_id, + id, + shm_desc, + shm_size + ); + return retval; +} + +NaClSrpcError PpbImageDataRpcClient::PPB_ImageData_GetNativeImageDataFormat( + NaClSrpcChannel* channel, + int32_t* format) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_ImageData_GetNativeImageDataFormat::i", + format + ); + return retval; +} + +NaClSrpcError PpbImageDataRpcClient::PPB_ImageData_IsImageDataFormatSupported( + NaClSrpcChannel* channel, + int32_t format, + int32_t* success) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_ImageData_IsImageDataFormatSupported:i:i", + format, + success + ); + return retval; +} + +NaClSrpcError PpbImageDataRpcClient::PPB_ImageData_Create( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t format, + nacl_abi_size_t size_bytes, char* size, + int32_t init_to_zero, + PP_Resource* resource) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_ImageData_Create:iiCi:i", + instance, + format, + size_bytes, size, + init_to_zero, + resource + ); + return retval; +} + +NaClSrpcError PpbImageDataRpcClient::PPB_ImageData_IsImageData( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* success) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_ImageData_IsImageData:i:i", + resource, + success + ); + return retval; +} + +NaClSrpcError PpbImageDataRpcClient::PPB_ImageData_Describe( + NaClSrpcChannel* channel, + PP_Resource resource, + nacl_abi_size_t* desc_bytes, char* desc, + NaClSrpcImcDescType* shm, + int32_t* shm_size, + int32_t* success) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_ImageData_Describe:i:Chii", + resource, + desc_bytes, desc, + shm, + shm_size, + success + ); + return retval; +} + +NaClSrpcError PpbInputEventRpcClient::PPB_InputEvent_RequestInputEvents( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t event_classes, + int32_t filtered, + int32_t* success) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_InputEvent_RequestInputEvents:iii:i", + instance, + event_classes, + filtered, + success + ); + return retval; +} + +NaClSrpcError PpbInputEventRpcClient::PPB_InputEvent_ClearInputEventRequest( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t event_classes) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_InputEvent_ClearInputEventRequest:ii:", + instance, + event_classes + ); + return retval; +} + +NaClSrpcError PpbInputEventRpcClient::PPB_InputEvent_CreateMouseInputEvent( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t type, + double time_stamp, + int32_t modifiers, + int32_t mouse_button, + int32_t mouse_position_x, + int32_t mouse_position_y, + int32_t click_count, + PP_Resource* resource_id) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_InputEvent_CreateMouseInputEvent:iidiiiii:i", + instance, + type, + time_stamp, + modifiers, + mouse_button, + mouse_position_x, + mouse_position_y, + click_count, + resource_id + ); + return retval; +} + +NaClSrpcError PpbInputEventRpcClient::PPB_InputEvent_CreateWheelInputEvent( + NaClSrpcChannel* channel, + PP_Instance instance, + double time_stamp, + int32_t modifiers, + double wheel_delta_x, + double wheel_delta_y, + double wheel_ticks_x, + double wheel_ticks_y, + int32_t scroll_by_page, + PP_Resource* resource_id) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_InputEvent_CreateWheelInputEvent:ididdddi:i", + instance, + time_stamp, + modifiers, + wheel_delta_x, + wheel_delta_y, + wheel_ticks_x, + wheel_ticks_y, + scroll_by_page, + resource_id + ); + return retval; +} + +NaClSrpcError PpbInputEventRpcClient::PPB_InputEvent_CreateKeyboardInputEvent( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t type, + double time_stamp, + int32_t modifiers, + int32_t key_code, + nacl_abi_size_t character_text_bytes, char* character_text, + PP_Resource* resource_id) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_InputEvent_CreateKeyboardInputEvent:iidiiC:i", + instance, + type, + time_stamp, + modifiers, + key_code, + character_text_bytes, character_text, + resource_id + ); + return retval; +} + +NaClSrpcError PpbInstanceRpcClient::PPB_Instance_BindGraphics( + NaClSrpcChannel* channel, + PP_Instance instance, + PP_Resource graphics_device, + int32_t* success) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Instance_BindGraphics:ii:i", + instance, + graphics_device, + success + ); + return retval; +} + +NaClSrpcError PpbInstanceRpcClient::PPB_Instance_IsFullFrame( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t* is_full_frame) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Instance_IsFullFrame:i:i", + instance, + is_full_frame + ); + return retval; +} + +NaClSrpcError PpbMessagingRpcClient::PPB_Messaging_PostMessage( + NaClSrpcChannel* channel, + PP_Instance instance, + nacl_abi_size_t message_bytes, char* message) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Messaging_PostMessage:iC:", + instance, + message_bytes, message + ); + return retval; +} + +NaClSrpcError PpbPdfRpcClient::PPB_PDF_GetLocalizedString( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t string_id, + nacl_abi_size_t* string_bytes, char* string) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_PDF_GetLocalizedString:ii:C", + instance, + string_id, + string_bytes, string + ); + return retval; +} + +NaClSrpcError PpbPdfRpcClient::PPB_PDF_GetResourceImage( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t image_id, + PP_Resource* image) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_PDF_GetResourceImage:ii:i", + instance, + image_id, + image + ); + return retval; +} + +NaClSrpcError PpbPdfRpcClient::PPB_PDF_GetFontFileWithFallback( + NaClSrpcChannel* channel, + PP_Instance instance, + nacl_abi_size_t description_bytes, char* description, + nacl_abi_size_t face_bytes, char* face, + int32_t charset, + PP_Resource* font) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_PDF_GetFontFileWithFallback:iCCi:i", + instance, + description_bytes, description, + face_bytes, face, + charset, + font + ); + return retval; +} + +NaClSrpcError PpbPdfRpcClient::PPB_PDF_GetFontTableForPrivateFontFile( + NaClSrpcChannel* channel, + PP_Resource font_file, + int32_t table, + nacl_abi_size_t* output_bytes, char* output, + int32_t* success) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_PDF_GetFontTableForPrivateFontFile:ii:Ci", + font_file, + table, + output_bytes, output, + success + ); + return retval; +} + +NaClSrpcError PpbPdfRpcClient::PPB_PDF_SearchString( + NaClSrpcChannel* channel, + PP_Instance instance, + nacl_abi_size_t string_bytes, char* string, + nacl_abi_size_t term_bytes, char* term, + int32_t case_sensitive, + nacl_abi_size_t* results_bytes, char* results, + int32_t* count) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_PDF_SearchString:iCCi:Ci", + instance, + string_bytes, string, + term_bytes, term, + case_sensitive, + results_bytes, results, + count + ); + return retval; +} + +NaClSrpcError PpbPdfRpcClient::PPB_PDF_DidStartLoading( + NaClSrpcChannel* channel, + PP_Instance instance) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_PDF_DidStartLoading:i:", + instance + ); + return retval; +} + +NaClSrpcError PpbPdfRpcClient::PPB_PDF_DidStopLoading( + NaClSrpcChannel* channel, + PP_Instance instance) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_PDF_DidStopLoading:i:", + instance + ); + return retval; +} + +NaClSrpcError PpbPdfRpcClient::PPB_PDF_SetContentRestriction( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t restrictions) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_PDF_SetContentRestriction:ii:", + instance, + restrictions + ); + return retval; +} + +NaClSrpcError PpbPdfRpcClient::PPB_PDF_HistogramPDFPageCount( + NaClSrpcChannel* channel, + int32_t count) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_PDF_HistogramPDFPageCount:i:", + count + ); + return retval; +} + +NaClSrpcError PpbPdfRpcClient::PPB_PDF_UserMetricsRecordAction( + NaClSrpcChannel* channel, + nacl_abi_size_t action_bytes, char* action) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_PDF_UserMetricsRecordAction:C:", + action_bytes, action + ); + return retval; +} + +NaClSrpcError PpbPdfRpcClient::PPB_PDF_HasUnsupportedFeature( + NaClSrpcChannel* channel, + PP_Instance instance) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_PDF_HasUnsupportedFeature:i:", + instance + ); + return retval; +} + +NaClSrpcError PpbPdfRpcClient::PPB_PDF_SaveAs( + NaClSrpcChannel* channel, + PP_Instance instance) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_PDF_SaveAs:i:", + instance + ); + return retval; +} + +NaClSrpcError PpbScrollbarRpcClient::PPB_Scrollbar_Create( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t vertical, + PP_Resource* scrollbar) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Scrollbar_Create:ii:i", + instance, + vertical, + scrollbar + ); + return retval; +} + +NaClSrpcError PpbScrollbarRpcClient::PPB_Scrollbar_IsScrollbar( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* is_scrollbar) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Scrollbar_IsScrollbar:i:i", + resource, + is_scrollbar + ); + return retval; +} + +NaClSrpcError PpbScrollbarRpcClient::PPB_Scrollbar_IsOverlay( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* is_overlay) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Scrollbar_IsOverlay:i:i", + resource, + is_overlay + ); + return retval; +} + +NaClSrpcError PpbScrollbarRpcClient::PPB_Scrollbar_GetThickness( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* thickness) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Scrollbar_GetThickness:i:i", + resource, + thickness + ); + return retval; +} + +NaClSrpcError PpbScrollbarRpcClient::PPB_Scrollbar_GetValue( + NaClSrpcChannel* channel, + PP_Resource scrollbar, + int32_t* value) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Scrollbar_GetValue:i:i", + scrollbar, + value + ); + return retval; +} + +NaClSrpcError PpbScrollbarRpcClient::PPB_Scrollbar_SetValue( + NaClSrpcChannel* channel, + PP_Resource scrollbar, + int32_t value) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Scrollbar_SetValue:ii:", + scrollbar, + value + ); + return retval; +} + +NaClSrpcError PpbScrollbarRpcClient::PPB_Scrollbar_SetDocumentSize( + NaClSrpcChannel* channel, + PP_Resource scrollbar, + int32_t size) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Scrollbar_SetDocumentSize:ii:", + scrollbar, + size + ); + return retval; +} + +NaClSrpcError PpbScrollbarRpcClient::PPB_Scrollbar_SetTickMarks( + NaClSrpcChannel* channel, + PP_Resource scrollbar, + nacl_abi_size_t tick_marks_bytes, char* tick_marks, + int32_t count) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Scrollbar_SetTickMarks:iCi:", + scrollbar, + tick_marks_bytes, tick_marks, + count + ); + return retval; +} + +NaClSrpcError PpbScrollbarRpcClient::PPB_Scrollbar_ScrollBy( + NaClSrpcChannel* channel, + PP_Resource scrollbar, + int32_t unit, + int32_t multiplier) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Scrollbar_ScrollBy:iii:", + scrollbar, + unit, + multiplier + ); + return retval; +} + +NaClSrpcError PpbTestingRpcClient::PPB_Testing_ReadImageData( + NaClSrpcChannel* channel, + PP_Resource device_context_2d, + PP_Resource image, + nacl_abi_size_t top_left_bytes, char* top_left, + int32_t* success) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Testing_ReadImageData:iiC:i", + device_context_2d, + image, + top_left_bytes, top_left, + success + ); + return retval; +} + +NaClSrpcError PpbTestingRpcClient::PPB_Testing_RunMessageLoop( + NaClSrpcChannel* channel, + PP_Instance instance) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Testing_RunMessageLoop:i:", + instance + ); + return retval; +} + +NaClSrpcError PpbTestingRpcClient::PPB_Testing_QuitMessageLoop( + NaClSrpcChannel* channel, + PP_Instance instance) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Testing_QuitMessageLoop:i:", + instance + ); + return retval; +} + +NaClSrpcError PpbTestingRpcClient::PPB_Testing_GetLiveObjectsForInstance( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t* live_object_count) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Testing_GetLiveObjectsForInstance:i:i", + instance, + live_object_count + ); + return retval; +} + +NaClSrpcError PpbURLLoaderRpcClient::PPB_URLLoader_Create( + NaClSrpcChannel* channel, + PP_Instance instance, + PP_Resource* resource) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_URLLoader_Create:i:i", + instance, + resource + ); + return retval; +} + +NaClSrpcError PpbURLLoaderRpcClient::PPB_URLLoader_IsURLLoader( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* is_url_loader) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_URLLoader_IsURLLoader:i:i", + resource, + is_url_loader + ); + return retval; +} + +NaClSrpcError PpbURLLoaderRpcClient::PPB_URLLoader_Open( + NaClSrpcChannel* channel, + PP_Resource loader, + PP_Resource request, + int32_t callback_id, + int32_t* pp_error) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_URLLoader_Open:iii:i", + loader, + request, + callback_id, + pp_error + ); + return retval; +} + +NaClSrpcError PpbURLLoaderRpcClient::PPB_URLLoader_FollowRedirect( + NaClSrpcChannel* channel, + PP_Resource loader, + int32_t callback_id, + int32_t* pp_error) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_URLLoader_FollowRedirect:ii:i", + loader, + callback_id, + pp_error + ); + return retval; +} + +NaClSrpcError PpbURLLoaderRpcClient::PPB_URLLoader_GetUploadProgress( + NaClSrpcChannel* channel, + PP_Resource loader, + int64_t* bytes_sent, + int64_t* total_bytes_to_be_sent, + int32_t* success) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_URLLoader_GetUploadProgress:i:lli", + loader, + bytes_sent, + total_bytes_to_be_sent, + success + ); + return retval; +} + +NaClSrpcError PpbURLLoaderRpcClient::PPB_URLLoader_GetDownloadProgress( + NaClSrpcChannel* channel, + PP_Resource loader, + int64_t* bytes_received, + int64_t* total_bytes_to_be_received, + int32_t* success) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_URLLoader_GetDownloadProgress:i:lli", + loader, + bytes_received, + total_bytes_to_be_received, + success + ); + return retval; +} + +NaClSrpcError PpbURLLoaderRpcClient::PPB_URLLoader_GetResponseInfo( + NaClSrpcChannel* channel, + PP_Resource loader, + PP_Resource* response) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_URLLoader_GetResponseInfo:i:i", + loader, + response + ); + return retval; +} + +NaClSrpcError PpbURLLoaderRpcClient::PPB_URLLoader_ReadResponseBody( + NaClSrpcChannel* channel, + PP_Resource loader, + int32_t bytes_to_read, + int32_t callback_id, + nacl_abi_size_t* buffer_bytes, char* buffer, + int32_t* pp_error_or_bytes) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_URLLoader_ReadResponseBody:iii:Ci", + loader, + bytes_to_read, + callback_id, + buffer_bytes, buffer, + pp_error_or_bytes + ); + return retval; +} + +NaClSrpcError PpbURLLoaderRpcClient::PPB_URLLoader_FinishStreamingToFile( + NaClSrpcChannel* channel, + PP_Resource loader, + int32_t callback_id, + int32_t* pp_error) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_URLLoader_FinishStreamingToFile:ii:i", + loader, + callback_id, + pp_error + ); + return retval; +} + +NaClSrpcError PpbURLLoaderRpcClient::PPB_URLLoader_Close( + NaClSrpcChannel* channel, + PP_Resource loader) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_URLLoader_Close:i:", + loader + ); + return retval; +} + +NaClSrpcError PpbURLRequestInfoRpcClient::PPB_URLRequestInfo_Create( + NaClSrpcChannel* channel, + PP_Instance instance, + PP_Resource* resource) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_URLRequestInfo_Create:i:i", + instance, + resource + ); + return retval; +} + +NaClSrpcError PpbURLRequestInfoRpcClient::PPB_URLRequestInfo_IsURLRequestInfo( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* success) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_URLRequestInfo_IsURLRequestInfo:i:i", + resource, + success + ); + return retval; +} + +NaClSrpcError PpbURLRequestInfoRpcClient::PPB_URLRequestInfo_SetProperty( + NaClSrpcChannel* channel, + PP_Resource request, + int32_t property, + nacl_abi_size_t value_bytes, char* value, + int32_t* success) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_URLRequestInfo_SetProperty:iiC:i", + request, + property, + value_bytes, value, + success + ); + return retval; +} + +NaClSrpcError PpbURLRequestInfoRpcClient::PPB_URLRequestInfo_AppendDataToBody( + NaClSrpcChannel* channel, + PP_Resource request, + nacl_abi_size_t data_bytes, char* data, + int32_t* success) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_URLRequestInfo_AppendDataToBody:iC:i", + request, + data_bytes, data, + success + ); + return retval; +} + +NaClSrpcError PpbURLRequestInfoRpcClient::PPB_URLRequestInfo_AppendFileToBody( + NaClSrpcChannel* channel, + PP_Resource request, + PP_Resource file_ref, + int64_t start_offset, + int64_t number_of_bytes, + double expected_last_modified_time, + int32_t* success) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_URLRequestInfo_AppendFileToBody:iilld:i", + request, + file_ref, + start_offset, + number_of_bytes, + expected_last_modified_time, + success + ); + return retval; +} + +NaClSrpcError PpbURLResponseInfoRpcClient::PPB_URLResponseInfo_IsURLResponseInfo( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* success) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_URLResponseInfo_IsURLResponseInfo:i:i", + resource, + success + ); + return retval; +} + +NaClSrpcError PpbURLResponseInfoRpcClient::PPB_URLResponseInfo_GetProperty( + NaClSrpcChannel* channel, + PP_Resource response, + int32_t property, + nacl_abi_size_t* value_bytes, char* value) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_URLResponseInfo_GetProperty:ii:C", + response, + property, + value_bytes, value + ); + return retval; +} + +NaClSrpcError PpbURLResponseInfoRpcClient::PPB_URLResponseInfo_GetBodyAsFileRef( + NaClSrpcChannel* channel, + PP_Resource response, + PP_Resource* file_ref) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_URLResponseInfo_GetBodyAsFileRef:i:i", + response, + file_ref + ); + return retval; +} + +NaClSrpcError PpbWidgetRpcClient::PPB_Widget_IsWidget( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* is_widget) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Widget_IsWidget:i:i", + resource, + is_widget + ); + return retval; +} + +NaClSrpcError PpbWidgetRpcClient::PPB_Widget_Paint( + NaClSrpcChannel* channel, + PP_Resource widget, + nacl_abi_size_t rect_bytes, char* rect, + PP_Resource image, + int32_t* success) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Widget_Paint:iCi:i", + widget, + rect_bytes, rect, + image, + success + ); + return retval; +} + +NaClSrpcError PpbWidgetRpcClient::PPB_Widget_HandleEvent( + NaClSrpcChannel* channel, + PP_Resource widget, + PP_Resource event, + int32_t* handled) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Widget_HandleEvent:ii:i", + widget, + event, + handled + ); + return retval; +} + +NaClSrpcError PpbWidgetRpcClient::PPB_Widget_GetLocation( + NaClSrpcChannel* channel, + PP_Resource widget, + nacl_abi_size_t* location_bytes, char* location, + int32_t* visible) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Widget_GetLocation:i:Ci", + widget, + location_bytes, location, + visible + ); + return retval; +} + +NaClSrpcError PpbWidgetRpcClient::PPB_Widget_SetLocation( + NaClSrpcChannel* channel, + PP_Resource widget, + nacl_abi_size_t location_bytes, char* location) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Widget_SetLocation:iC:", + widget, + location_bytes, location + ); + return retval; +} + +NaClSrpcError PpbZoomRpcClient::PPB_Zoom_ZoomChanged( + NaClSrpcChannel* channel, + PP_Instance instance, + double factor) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Zoom_ZoomChanged:id:", + instance, + factor + ); + return retval; +} + +NaClSrpcError PpbZoomRpcClient::PPB_Zoom_ZoomLimitsChanged( + NaClSrpcChannel* channel, + PP_Instance instance, + double minimum_factor, + double maximum_factor) { + VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), + ("%s: PPAPI calls are not supported off the main thread\n", + __FUNCTION__)); + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Zoom_ZoomLimitsChanged:idd:", + instance, + minimum_factor, + maximum_factor + ); + return retval; +} + + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppb_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/ppb_rpc_server.cc new file mode 100644 index 0000000..e436d3a --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppb_rpc_server.cc @@ -0,0 +1,2337 @@ +// 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. +// +// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING +// +// Automatically generated code. See srpcgen.py +// +// NaCl Simple Remote Procedure Call interface abstractions. + +#include "trusted/srpcgen/ppb_rpc.h" +#ifdef __native_client__ +#ifndef UNREFERENCED_PARAMETER +#define UNREFERENCED_PARAMETER(P) do { (void) P; } while (0) +#endif // UNREFERENCED_PARAMETER +#else +#include "native_client/src/include/portability.h" +#endif // __native_client__ +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_resource.h" + +namespace { + +static void StreamAsFileDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + NaClFileRpcServer::StreamAsFile( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->arrays.str, + inputs[2]->u.ival + ); +} + +static void GetFileDescDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + NaClFileRpcServer::GetFileDesc( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->arrays.str, + &(outputs[0]->u.hval) + ); +} + +static void PPB_GetInterfaceDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbRpcServer::PPB_GetInterface( + rpc, + done, + inputs[0]->arrays.str, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Audio_CreateDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbAudioRpcServer::PPB_Audio_Create( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Audio_IsAudioDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbAudioRpcServer::PPB_Audio_IsAudio( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Audio_GetCurrentConfigDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbAudioRpcServer::PPB_Audio_GetCurrentConfig( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Audio_StopPlaybackDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbAudioRpcServer::PPB_Audio_StopPlayback( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Audio_StartPlaybackDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbAudioRpcServer::PPB_Audio_StartPlayback( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_AudioConfig_CreateStereo16BitDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbAudioConfigRpcServer::PPB_AudioConfig_CreateStereo16Bit( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + inputs[2]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_AudioConfig_IsAudioConfigDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbAudioConfigRpcServer::PPB_AudioConfig_IsAudioConfig( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_AudioConfig_RecommendSampleFrameCountDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbAudioConfigRpcServer::PPB_AudioConfig_RecommendSampleFrameCount( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_AudioConfig_GetSampleRateDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbAudioConfigRpcServer::PPB_AudioConfig_GetSampleRate( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_AudioConfig_GetSampleFrameCountDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbAudioConfigRpcServer::PPB_AudioConfig_GetSampleFrameCount( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Core_AddRefResourceDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PpbCoreRpcServer::PPB_Core_AddRefResource( + rpc, + done, + inputs[0]->u.ival + ); +} + +static void PPB_Core_ReleaseResourceDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PpbCoreRpcServer::PPB_Core_ReleaseResource( + rpc, + done, + inputs[0]->u.ival + ); +} + +static void ReleaseResourceMultipleTimesDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PpbCoreRpcServer::ReleaseResourceMultipleTimes( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival + ); +} + +static void PPB_Core_GetTimeDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(inputs); + PpbCoreRpcServer::PPB_Core_GetTime( + rpc, + done, + &(outputs[0]->u.dval) + ); +} + +static void PPB_Core_GetTimeTicksDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(inputs); + PpbCoreRpcServer::PPB_Core_GetTimeTicks( + rpc, + done, + &(outputs[0]->u.dval) + ); +} + +static void PPB_Core_CallOnMainThreadDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PpbCoreRpcServer::PPB_Core_CallOnMainThread( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + inputs[2]->u.ival + ); +} + +static void PPB_CursorControl_SetCursorDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbCursorControlRpcServer::PPB_CursorControl_SetCursor( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + inputs[2]->u.ival, + inputs[3]->u.count, inputs[3]->arrays.carr, + &(outputs[0]->u.ival) + ); +} + +static void PPB_CursorControl_LockCursorDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbCursorControlRpcServer::PPB_CursorControl_LockCursor( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_CursorControl_UnlockCursorDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbCursorControlRpcServer::PPB_CursorControl_UnlockCursor( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_CursorControl_HasCursorLockDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbCursorControlRpcServer::PPB_CursorControl_HasCursorLock( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_CursorControl_CanLockCursorDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbCursorControlRpcServer::PPB_CursorControl_CanLockCursor( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_FileIO_CreateDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbFileIORpcServer::PPB_FileIO_Create( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_FileIO_IsFileIODispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbFileIORpcServer::PPB_FileIO_IsFileIO( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_FileIO_OpenDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbFileIORpcServer::PPB_FileIO_Open( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + inputs[2]->u.ival, + inputs[3]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_FileIO_QueryDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbFileIORpcServer::PPB_FileIO_Query( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + inputs[2]->u.ival, + &(outputs[0]->u.count), outputs[0]->arrays.carr, + &(outputs[1]->u.ival) + ); +} + +static void PPB_FileIO_TouchDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbFileIORpcServer::PPB_FileIO_Touch( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.dval, + inputs[2]->u.dval, + inputs[3]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_FileIO_ReadDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbFileIORpcServer::PPB_FileIO_Read( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.lval, + inputs[2]->u.ival, + inputs[3]->u.ival, + &(outputs[0]->u.count), outputs[0]->arrays.carr, + &(outputs[1]->u.ival) + ); +} + +static void PPB_FileIO_WriteDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbFileIORpcServer::PPB_FileIO_Write( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.lval, + inputs[2]->u.count, inputs[2]->arrays.carr, + inputs[3]->u.ival, + inputs[4]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_FileIO_SetLengthDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbFileIORpcServer::PPB_FileIO_SetLength( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.lval, + inputs[2]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_FileIO_FlushDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbFileIORpcServer::PPB_FileIO_Flush( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_FileIO_CloseDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PpbFileIORpcServer::PPB_FileIO_Close( + rpc, + done, + inputs[0]->u.ival + ); +} + +static void PPB_FileRef_CreateDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbFileRefRpcServer::PPB_FileRef_Create( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.count, inputs[1]->arrays.carr, + &(outputs[0]->u.ival) + ); +} + +static void PPB_FileRef_IsFileRefDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbFileRefRpcServer::PPB_FileRef_IsFileRef( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_FileRef_GetFileSystemTypeDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbFileRefRpcServer::PPB_FileRef_GetFileSystemType( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_FileRef_GetNameDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbFileRefRpcServer::PPB_FileRef_GetName( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.count), outputs[0]->arrays.carr + ); +} + +static void PPB_FileRef_GetPathDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbFileRefRpcServer::PPB_FileRef_GetPath( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.count), outputs[0]->arrays.carr + ); +} + +static void PPB_FileRef_GetParentDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbFileRefRpcServer::PPB_FileRef_GetParent( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_FileRef_MakeDirectoryDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbFileRefRpcServer::PPB_FileRef_MakeDirectory( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + inputs[2]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_FileRef_TouchDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbFileRefRpcServer::PPB_FileRef_Touch( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.dval, + inputs[2]->u.dval, + inputs[3]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_FileRef_DeleteDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbFileRefRpcServer::PPB_FileRef_Delete( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_FileRef_RenameDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbFileRefRpcServer::PPB_FileRef_Rename( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + inputs[2]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_FileSystem_CreateDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbFileSystemRpcServer::PPB_FileSystem_Create( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_FileSystem_IsFileSystemDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbFileSystemRpcServer::PPB_FileSystem_IsFileSystem( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_FileSystem_OpenDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbFileSystemRpcServer::PPB_FileSystem_Open( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.lval, + inputs[2]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_FileSystem_GetTypeDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbFileSystemRpcServer::PPB_FileSystem_GetType( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Find_NumberOfFindResultsChangedDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PpbFindRpcServer::PPB_Find_NumberOfFindResultsChanged( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + inputs[2]->u.ival + ); +} + +static void PPB_Find_SelectedFindResultChangedDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PpbFindRpcServer::PPB_Find_SelectedFindResultChanged( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival + ); +} + +static void PPB_Font_GetFontFamiliesDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbFontRpcServer::PPB_Font_GetFontFamilies( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.count), outputs[0]->arrays.carr + ); +} + +static void PPB_Font_CreateDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbFontRpcServer::PPB_Font_Create( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.count, inputs[1]->arrays.carr, + inputs[2]->u.count, inputs[2]->arrays.carr, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Font_IsFontDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbFontRpcServer::PPB_Font_IsFont( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Font_DescribeDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbFontRpcServer::PPB_Font_Describe( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.count), outputs[0]->arrays.carr, + &(outputs[1]->u.count), outputs[1]->arrays.carr, + &(outputs[2]->u.count), outputs[2]->arrays.carr, + &(outputs[3]->u.ival) + ); +} + +static void PPB_Font_DrawTextAtDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbFontRpcServer::PPB_Font_DrawTextAt( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + inputs[2]->u.count, inputs[2]->arrays.carr, + inputs[3]->u.count, inputs[3]->arrays.carr, + inputs[4]->u.count, inputs[4]->arrays.carr, + inputs[5]->u.ival, + inputs[6]->u.count, inputs[6]->arrays.carr, + inputs[7]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Font_MeasureTextDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbFontRpcServer::PPB_Font_MeasureText( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.count, inputs[1]->arrays.carr, + inputs[2]->u.count, inputs[2]->arrays.carr, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Font_CharacterOffsetForPixelDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbFontRpcServer::PPB_Font_CharacterOffsetForPixel( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.count, inputs[1]->arrays.carr, + inputs[2]->u.count, inputs[2]->arrays.carr, + inputs[3]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Font_PixelOffsetForCharacterDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbFontRpcServer::PPB_Font_PixelOffsetForCharacter( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.count, inputs[1]->arrays.carr, + inputs[2]->u.count, inputs[2]->arrays.carr, + inputs[3]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Graphics2D_CreateDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbGraphics2DRpcServer::PPB_Graphics2D_Create( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.count, inputs[1]->arrays.carr, + inputs[2]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Graphics2D_IsGraphics2DDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbGraphics2DRpcServer::PPB_Graphics2D_IsGraphics2D( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Graphics2D_DescribeDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbGraphics2DRpcServer::PPB_Graphics2D_Describe( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.count), outputs[0]->arrays.carr, + &(outputs[1]->u.ival), + &(outputs[2]->u.ival) + ); +} + +static void PPB_Graphics2D_PaintImageDataDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PpbGraphics2DRpcServer::PPB_Graphics2D_PaintImageData( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + inputs[2]->u.count, inputs[2]->arrays.carr, + inputs[3]->u.count, inputs[3]->arrays.carr + ); +} + +static void PPB_Graphics2D_ScrollDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PpbGraphics2DRpcServer::PPB_Graphics2D_Scroll( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.count, inputs[1]->arrays.carr, + inputs[2]->u.count, inputs[2]->arrays.carr + ); +} + +static void PPB_Graphics2D_ReplaceContentsDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PpbGraphics2DRpcServer::PPB_Graphics2D_ReplaceContents( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival + ); +} + +static void PPB_Graphics2D_FlushDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbGraphics2DRpcServer::PPB_Graphics2D_Flush( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Graphics3D_CreateDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbGraphics3DRpcServer::PPB_Graphics3D_Create( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + inputs[2]->u.count, inputs[2]->arrays.iarr, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Graphics3D_GetAttribsDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbGraphics3DRpcServer::PPB_Graphics3D_GetAttribs( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.count, inputs[1]->arrays.iarr, + &(outputs[0]->u.count), outputs[0]->arrays.iarr, + &(outputs[1]->u.ival) + ); +} + +static void PPB_Graphics3D_SetAttribsDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbGraphics3DRpcServer::PPB_Graphics3D_SetAttribs( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.count, inputs[1]->arrays.iarr, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Graphics3D_ResizeBuffersDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbGraphics3DRpcServer::PPB_Graphics3D_ResizeBuffers( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + inputs[2]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Graphics3D_SwapBuffersDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbGraphics3DRpcServer::PPB_Graphics3D_SwapBuffers( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Graphics3DTrusted_CreateRawDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbGraphics3DRpcServer::PPB_Graphics3DTrusted_CreateRaw( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + inputs[2]->u.count, inputs[2]->arrays.iarr, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Graphics3DTrusted_InitCommandBufferDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbGraphics3DRpcServer::PPB_Graphics3DTrusted_InitCommandBuffer( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Graphics3DTrusted_GetRingBufferDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbGraphics3DRpcServer::PPB_Graphics3DTrusted_GetRingBuffer( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.hval), + &(outputs[1]->u.ival) + ); +} + +static void PPB_Graphics3DTrusted_GetStateDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbGraphics3DRpcServer::PPB_Graphics3DTrusted_GetState( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.count), outputs[0]->arrays.carr + ); +} + +static void PPB_Graphics3DTrusted_FlushDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PpbGraphics3DRpcServer::PPB_Graphics3DTrusted_Flush( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival + ); +} + +static void PPB_Graphics3DTrusted_FlushSyncDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbGraphics3DRpcServer::PPB_Graphics3DTrusted_FlushSync( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + &(outputs[0]->u.count), outputs[0]->arrays.carr + ); +} + +static void PPB_Graphics3DTrusted_CreateTransferBufferDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbGraphics3DRpcServer::PPB_Graphics3DTrusted_CreateTransferBuffer( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + inputs[2]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Graphics3DTrusted_DestroyTransferBufferDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PpbGraphics3DRpcServer::PPB_Graphics3DTrusted_DestroyTransferBuffer( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival + ); +} + +static void PPB_Graphics3DTrusted_GetTransferBufferDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbGraphics3DRpcServer::PPB_Graphics3DTrusted_GetTransferBuffer( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + &(outputs[0]->u.hval), + &(outputs[1]->u.ival) + ); +} + +static void PPB_ImageData_GetNativeImageDataFormatDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(inputs); + PpbImageDataRpcServer::PPB_ImageData_GetNativeImageDataFormat( + rpc, + done, + &(outputs[0]->u.ival) + ); +} + +static void PPB_ImageData_IsImageDataFormatSupportedDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbImageDataRpcServer::PPB_ImageData_IsImageDataFormatSupported( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_ImageData_CreateDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbImageDataRpcServer::PPB_ImageData_Create( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + inputs[2]->u.count, inputs[2]->arrays.carr, + inputs[3]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_ImageData_IsImageDataDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbImageDataRpcServer::PPB_ImageData_IsImageData( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_ImageData_DescribeDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbImageDataRpcServer::PPB_ImageData_Describe( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.count), outputs[0]->arrays.carr, + &(outputs[1]->u.hval), + &(outputs[2]->u.ival), + &(outputs[3]->u.ival) + ); +} + +static void PPB_InputEvent_RequestInputEventsDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbInputEventRpcServer::PPB_InputEvent_RequestInputEvents( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + inputs[2]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_InputEvent_ClearInputEventRequestDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PpbInputEventRpcServer::PPB_InputEvent_ClearInputEventRequest( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival + ); +} + +static void PPB_InputEvent_CreateMouseInputEventDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbInputEventRpcServer::PPB_InputEvent_CreateMouseInputEvent( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + inputs[2]->u.dval, + inputs[3]->u.ival, + inputs[4]->u.ival, + inputs[5]->u.ival, + inputs[6]->u.ival, + inputs[7]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_InputEvent_CreateWheelInputEventDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbInputEventRpcServer::PPB_InputEvent_CreateWheelInputEvent( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.dval, + inputs[2]->u.ival, + inputs[3]->u.dval, + inputs[4]->u.dval, + inputs[5]->u.dval, + inputs[6]->u.dval, + inputs[7]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_InputEvent_CreateKeyboardInputEventDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbInputEventRpcServer::PPB_InputEvent_CreateKeyboardInputEvent( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + inputs[2]->u.dval, + inputs[3]->u.ival, + inputs[4]->u.ival, + inputs[5]->u.count, inputs[5]->arrays.carr, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Instance_BindGraphicsDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbInstanceRpcServer::PPB_Instance_BindGraphics( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Instance_IsFullFrameDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbInstanceRpcServer::PPB_Instance_IsFullFrame( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Messaging_PostMessageDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PpbMessagingRpcServer::PPB_Messaging_PostMessage( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.count, inputs[1]->arrays.carr + ); +} + +static void PPB_PDF_GetLocalizedStringDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbPdfRpcServer::PPB_PDF_GetLocalizedString( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + &(outputs[0]->u.count), outputs[0]->arrays.carr + ); +} + +static void PPB_PDF_GetResourceImageDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbPdfRpcServer::PPB_PDF_GetResourceImage( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_PDF_GetFontFileWithFallbackDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbPdfRpcServer::PPB_PDF_GetFontFileWithFallback( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.count, inputs[1]->arrays.carr, + inputs[2]->u.count, inputs[2]->arrays.carr, + inputs[3]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_PDF_GetFontTableForPrivateFontFileDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbPdfRpcServer::PPB_PDF_GetFontTableForPrivateFontFile( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + &(outputs[0]->u.count), outputs[0]->arrays.carr, + &(outputs[1]->u.ival) + ); +} + +static void PPB_PDF_SearchStringDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbPdfRpcServer::PPB_PDF_SearchString( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.count, inputs[1]->arrays.carr, + inputs[2]->u.count, inputs[2]->arrays.carr, + inputs[3]->u.ival, + &(outputs[0]->u.count), outputs[0]->arrays.carr, + &(outputs[1]->u.ival) + ); +} + +static void PPB_PDF_DidStartLoadingDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PpbPdfRpcServer::PPB_PDF_DidStartLoading( + rpc, + done, + inputs[0]->u.ival + ); +} + +static void PPB_PDF_DidStopLoadingDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PpbPdfRpcServer::PPB_PDF_DidStopLoading( + rpc, + done, + inputs[0]->u.ival + ); +} + +static void PPB_PDF_SetContentRestrictionDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PpbPdfRpcServer::PPB_PDF_SetContentRestriction( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival + ); +} + +static void PPB_PDF_HistogramPDFPageCountDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PpbPdfRpcServer::PPB_PDF_HistogramPDFPageCount( + rpc, + done, + inputs[0]->u.ival + ); +} + +static void PPB_PDF_UserMetricsRecordActionDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PpbPdfRpcServer::PPB_PDF_UserMetricsRecordAction( + rpc, + done, + inputs[0]->u.count, inputs[0]->arrays.carr + ); +} + +static void PPB_PDF_HasUnsupportedFeatureDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PpbPdfRpcServer::PPB_PDF_HasUnsupportedFeature( + rpc, + done, + inputs[0]->u.ival + ); +} + +static void PPB_PDF_SaveAsDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PpbPdfRpcServer::PPB_PDF_SaveAs( + rpc, + done, + inputs[0]->u.ival + ); +} + +static void PPB_Scrollbar_CreateDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbScrollbarRpcServer::PPB_Scrollbar_Create( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Scrollbar_IsScrollbarDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbScrollbarRpcServer::PPB_Scrollbar_IsScrollbar( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Scrollbar_IsOverlayDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbScrollbarRpcServer::PPB_Scrollbar_IsOverlay( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Scrollbar_GetThicknessDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbScrollbarRpcServer::PPB_Scrollbar_GetThickness( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Scrollbar_GetValueDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbScrollbarRpcServer::PPB_Scrollbar_GetValue( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Scrollbar_SetValueDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PpbScrollbarRpcServer::PPB_Scrollbar_SetValue( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival + ); +} + +static void PPB_Scrollbar_SetDocumentSizeDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PpbScrollbarRpcServer::PPB_Scrollbar_SetDocumentSize( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival + ); +} + +static void PPB_Scrollbar_SetTickMarksDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PpbScrollbarRpcServer::PPB_Scrollbar_SetTickMarks( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.count, inputs[1]->arrays.carr, + inputs[2]->u.ival + ); +} + +static void PPB_Scrollbar_ScrollByDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PpbScrollbarRpcServer::PPB_Scrollbar_ScrollBy( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + inputs[2]->u.ival + ); +} + +static void PPB_Testing_ReadImageDataDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbTestingRpcServer::PPB_Testing_ReadImageData( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + inputs[2]->u.count, inputs[2]->arrays.carr, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Testing_RunMessageLoopDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PpbTestingRpcServer::PPB_Testing_RunMessageLoop( + rpc, + done, + inputs[0]->u.ival + ); +} + +static void PPB_Testing_QuitMessageLoopDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PpbTestingRpcServer::PPB_Testing_QuitMessageLoop( + rpc, + done, + inputs[0]->u.ival + ); +} + +static void PPB_Testing_GetLiveObjectsForInstanceDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbTestingRpcServer::PPB_Testing_GetLiveObjectsForInstance( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_URLLoader_CreateDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbURLLoaderRpcServer::PPB_URLLoader_Create( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_URLLoader_IsURLLoaderDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbURLLoaderRpcServer::PPB_URLLoader_IsURLLoader( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_URLLoader_OpenDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbURLLoaderRpcServer::PPB_URLLoader_Open( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + inputs[2]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_URLLoader_FollowRedirectDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbURLLoaderRpcServer::PPB_URLLoader_FollowRedirect( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_URLLoader_GetUploadProgressDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbURLLoaderRpcServer::PPB_URLLoader_GetUploadProgress( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.lval), + &(outputs[1]->u.lval), + &(outputs[2]->u.ival) + ); +} + +static void PPB_URLLoader_GetDownloadProgressDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbURLLoaderRpcServer::PPB_URLLoader_GetDownloadProgress( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.lval), + &(outputs[1]->u.lval), + &(outputs[2]->u.ival) + ); +} + +static void PPB_URLLoader_GetResponseInfoDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbURLLoaderRpcServer::PPB_URLLoader_GetResponseInfo( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_URLLoader_ReadResponseBodyDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbURLLoaderRpcServer::PPB_URLLoader_ReadResponseBody( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + inputs[2]->u.ival, + &(outputs[0]->u.count), outputs[0]->arrays.carr, + &(outputs[1]->u.ival) + ); +} + +static void PPB_URLLoader_FinishStreamingToFileDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbURLLoaderRpcServer::PPB_URLLoader_FinishStreamingToFile( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_URLLoader_CloseDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PpbURLLoaderRpcServer::PPB_URLLoader_Close( + rpc, + done, + inputs[0]->u.ival + ); +} + +static void PPB_URLRequestInfo_CreateDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbURLRequestInfoRpcServer::PPB_URLRequestInfo_Create( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_URLRequestInfo_IsURLRequestInfoDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbURLRequestInfoRpcServer::PPB_URLRequestInfo_IsURLRequestInfo( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_URLRequestInfo_SetPropertyDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbURLRequestInfoRpcServer::PPB_URLRequestInfo_SetProperty( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + inputs[2]->u.count, inputs[2]->arrays.carr, + &(outputs[0]->u.ival) + ); +} + +static void PPB_URLRequestInfo_AppendDataToBodyDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbURLRequestInfoRpcServer::PPB_URLRequestInfo_AppendDataToBody( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.count, inputs[1]->arrays.carr, + &(outputs[0]->u.ival) + ); +} + +static void PPB_URLRequestInfo_AppendFileToBodyDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbURLRequestInfoRpcServer::PPB_URLRequestInfo_AppendFileToBody( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + inputs[2]->u.lval, + inputs[3]->u.lval, + inputs[4]->u.dval, + &(outputs[0]->u.ival) + ); +} + +static void PPB_URLResponseInfo_IsURLResponseInfoDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbURLResponseInfoRpcServer::PPB_URLResponseInfo_IsURLResponseInfo( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_URLResponseInfo_GetPropertyDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbURLResponseInfoRpcServer::PPB_URLResponseInfo_GetProperty( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + &(outputs[0]->u.count), outputs[0]->arrays.carr + ); +} + +static void PPB_URLResponseInfo_GetBodyAsFileRefDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbURLResponseInfoRpcServer::PPB_URLResponseInfo_GetBodyAsFileRef( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Widget_IsWidgetDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbWidgetRpcServer::PPB_Widget_IsWidget( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Widget_PaintDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbWidgetRpcServer::PPB_Widget_Paint( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.count, inputs[1]->arrays.carr, + inputs[2]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Widget_HandleEventDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbWidgetRpcServer::PPB_Widget_HandleEvent( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPB_Widget_GetLocationDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PpbWidgetRpcServer::PPB_Widget_GetLocation( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.count), outputs[0]->arrays.carr, + &(outputs[1]->u.ival) + ); +} + +static void PPB_Widget_SetLocationDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PpbWidgetRpcServer::PPB_Widget_SetLocation( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.count, inputs[1]->arrays.carr + ); +} + +static void PPB_Zoom_ZoomChangedDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PpbZoomRpcServer::PPB_Zoom_ZoomChanged( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.dval + ); +} + +static void PPB_Zoom_ZoomLimitsChangedDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PpbZoomRpcServer::PPB_Zoom_ZoomLimitsChanged( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.dval, + inputs[2]->u.dval + ); +} + +} // namespace + +NaClSrpcHandlerDesc PpbRpcs::srpc_methods[] = { + { "StreamAsFile:isi:", StreamAsFileDispatcher }, + { "GetFileDesc:is:h", GetFileDescDispatcher }, + { "PPB_GetInterface:s:i", PPB_GetInterfaceDispatcher }, + { "PPB_Audio_Create:ii:i", PPB_Audio_CreateDispatcher }, + { "PPB_Audio_IsAudio:i:i", PPB_Audio_IsAudioDispatcher }, + { "PPB_Audio_GetCurrentConfig:i:i", PPB_Audio_GetCurrentConfigDispatcher }, + { "PPB_Audio_StopPlayback:i:i", PPB_Audio_StopPlaybackDispatcher }, + { "PPB_Audio_StartPlayback:i:i", PPB_Audio_StartPlaybackDispatcher }, + { "PPB_AudioConfig_CreateStereo16Bit:iii:i", PPB_AudioConfig_CreateStereo16BitDispatcher }, + { "PPB_AudioConfig_IsAudioConfig:i:i", PPB_AudioConfig_IsAudioConfigDispatcher }, + { "PPB_AudioConfig_RecommendSampleFrameCount:ii:i", PPB_AudioConfig_RecommendSampleFrameCountDispatcher }, + { "PPB_AudioConfig_GetSampleRate:i:i", PPB_AudioConfig_GetSampleRateDispatcher }, + { "PPB_AudioConfig_GetSampleFrameCount:i:i", PPB_AudioConfig_GetSampleFrameCountDispatcher }, + { "PPB_Core_AddRefResource:i:", PPB_Core_AddRefResourceDispatcher }, + { "PPB_Core_ReleaseResource:i:", PPB_Core_ReleaseResourceDispatcher }, + { "ReleaseResourceMultipleTimes:ii:", ReleaseResourceMultipleTimesDispatcher }, + { "PPB_Core_GetTime::d", PPB_Core_GetTimeDispatcher }, + { "PPB_Core_GetTimeTicks::d", PPB_Core_GetTimeTicksDispatcher }, + { "PPB_Core_CallOnMainThread:iii:", PPB_Core_CallOnMainThreadDispatcher }, + { "PPB_CursorControl_SetCursor:iiiC:i", PPB_CursorControl_SetCursorDispatcher }, + { "PPB_CursorControl_LockCursor:i:i", PPB_CursorControl_LockCursorDispatcher }, + { "PPB_CursorControl_UnlockCursor:i:i", PPB_CursorControl_UnlockCursorDispatcher }, + { "PPB_CursorControl_HasCursorLock:i:i", PPB_CursorControl_HasCursorLockDispatcher }, + { "PPB_CursorControl_CanLockCursor:i:i", PPB_CursorControl_CanLockCursorDispatcher }, + { "PPB_FileIO_Create:i:i", PPB_FileIO_CreateDispatcher }, + { "PPB_FileIO_IsFileIO:i:i", PPB_FileIO_IsFileIODispatcher }, + { "PPB_FileIO_Open:iiii:i", PPB_FileIO_OpenDispatcher }, + { "PPB_FileIO_Query:iii:Ci", PPB_FileIO_QueryDispatcher }, + { "PPB_FileIO_Touch:iddi:i", PPB_FileIO_TouchDispatcher }, + { "PPB_FileIO_Read:ilii:Ci", PPB_FileIO_ReadDispatcher }, + { "PPB_FileIO_Write:ilCii:i", PPB_FileIO_WriteDispatcher }, + { "PPB_FileIO_SetLength:ili:i", PPB_FileIO_SetLengthDispatcher }, + { "PPB_FileIO_Flush:ii:i", PPB_FileIO_FlushDispatcher }, + { "PPB_FileIO_Close:i:", PPB_FileIO_CloseDispatcher }, + { "PPB_FileRef_Create:iC:i", PPB_FileRef_CreateDispatcher }, + { "PPB_FileRef_IsFileRef:i:i", PPB_FileRef_IsFileRefDispatcher }, + { "PPB_FileRef_GetFileSystemType:i:i", PPB_FileRef_GetFileSystemTypeDispatcher }, + { "PPB_FileRef_GetName:i:C", PPB_FileRef_GetNameDispatcher }, + { "PPB_FileRef_GetPath:i:C", PPB_FileRef_GetPathDispatcher }, + { "PPB_FileRef_GetParent:i:i", PPB_FileRef_GetParentDispatcher }, + { "PPB_FileRef_MakeDirectory:iii:i", PPB_FileRef_MakeDirectoryDispatcher }, + { "PPB_FileRef_Touch:iddi:i", PPB_FileRef_TouchDispatcher }, + { "PPB_FileRef_Delete:ii:i", PPB_FileRef_DeleteDispatcher }, + { "PPB_FileRef_Rename:iii:i", PPB_FileRef_RenameDispatcher }, + { "PPB_FileSystem_Create:ii:i", PPB_FileSystem_CreateDispatcher }, + { "PPB_FileSystem_IsFileSystem:i:i", PPB_FileSystem_IsFileSystemDispatcher }, + { "PPB_FileSystem_Open:ili:i", PPB_FileSystem_OpenDispatcher }, + { "PPB_FileSystem_GetType:i:i", PPB_FileSystem_GetTypeDispatcher }, + { "PPB_Find_NumberOfFindResultsChanged:iii:", PPB_Find_NumberOfFindResultsChangedDispatcher }, + { "PPB_Find_SelectedFindResultChanged:ii:", PPB_Find_SelectedFindResultChangedDispatcher }, + { "PPB_Font_GetFontFamilies:i:C", PPB_Font_GetFontFamiliesDispatcher }, + { "PPB_Font_Create:iCC:i", PPB_Font_CreateDispatcher }, + { "PPB_Font_IsFont:i:i", PPB_Font_IsFontDispatcher }, + { "PPB_Font_Describe:i:CCCi", PPB_Font_DescribeDispatcher }, + { "PPB_Font_DrawTextAt:iiCCCiCi:i", PPB_Font_DrawTextAtDispatcher }, + { "PPB_Font_MeasureText:iCC:i", PPB_Font_MeasureTextDispatcher }, + { "PPB_Font_CharacterOffsetForPixel:iCCi:i", PPB_Font_CharacterOffsetForPixelDispatcher }, + { "PPB_Font_PixelOffsetForCharacter:iCCi:i", PPB_Font_PixelOffsetForCharacterDispatcher }, + { "PPB_Graphics2D_Create:iCi:i", PPB_Graphics2D_CreateDispatcher }, + { "PPB_Graphics2D_IsGraphics2D:i:i", PPB_Graphics2D_IsGraphics2DDispatcher }, + { "PPB_Graphics2D_Describe:i:Cii", PPB_Graphics2D_DescribeDispatcher }, + { "PPB_Graphics2D_PaintImageData:iiCC:", PPB_Graphics2D_PaintImageDataDispatcher }, + { "PPB_Graphics2D_Scroll:iCC:", PPB_Graphics2D_ScrollDispatcher }, + { "PPB_Graphics2D_ReplaceContents:ii:", PPB_Graphics2D_ReplaceContentsDispatcher }, + { "PPB_Graphics2D_Flush:ii:i", PPB_Graphics2D_FlushDispatcher }, + { "PPB_Graphics3D_Create:iiI:i", PPB_Graphics3D_CreateDispatcher }, + { "PPB_Graphics3D_GetAttribs:iI:Ii", PPB_Graphics3D_GetAttribsDispatcher }, + { "PPB_Graphics3D_SetAttribs:iI:i", PPB_Graphics3D_SetAttribsDispatcher }, + { "PPB_Graphics3D_ResizeBuffers:iii:i", PPB_Graphics3D_ResizeBuffersDispatcher }, + { "PPB_Graphics3D_SwapBuffers:ii:i", PPB_Graphics3D_SwapBuffersDispatcher }, + { "PPB_Graphics3DTrusted_CreateRaw:iiI:i", PPB_Graphics3DTrusted_CreateRawDispatcher }, + { "PPB_Graphics3DTrusted_InitCommandBuffer:ii:i", PPB_Graphics3DTrusted_InitCommandBufferDispatcher }, + { "PPB_Graphics3DTrusted_GetRingBuffer:i:hi", PPB_Graphics3DTrusted_GetRingBufferDispatcher }, + { "PPB_Graphics3DTrusted_GetState:i:C", PPB_Graphics3DTrusted_GetStateDispatcher }, + { "PPB_Graphics3DTrusted_Flush:ii:", PPB_Graphics3DTrusted_FlushDispatcher }, + { "PPB_Graphics3DTrusted_FlushSync:ii:C", PPB_Graphics3DTrusted_FlushSyncDispatcher }, + { "PPB_Graphics3DTrusted_CreateTransferBuffer:iii:i", PPB_Graphics3DTrusted_CreateTransferBufferDispatcher }, + { "PPB_Graphics3DTrusted_DestroyTransferBuffer:ii:", PPB_Graphics3DTrusted_DestroyTransferBufferDispatcher }, + { "PPB_Graphics3DTrusted_GetTransferBuffer:ii:hi", PPB_Graphics3DTrusted_GetTransferBufferDispatcher }, + { "PPB_ImageData_GetNativeImageDataFormat::i", PPB_ImageData_GetNativeImageDataFormatDispatcher }, + { "PPB_ImageData_IsImageDataFormatSupported:i:i", PPB_ImageData_IsImageDataFormatSupportedDispatcher }, + { "PPB_ImageData_Create:iiCi:i", PPB_ImageData_CreateDispatcher }, + { "PPB_ImageData_IsImageData:i:i", PPB_ImageData_IsImageDataDispatcher }, + { "PPB_ImageData_Describe:i:Chii", PPB_ImageData_DescribeDispatcher }, + { "PPB_InputEvent_RequestInputEvents:iii:i", PPB_InputEvent_RequestInputEventsDispatcher }, + { "PPB_InputEvent_ClearInputEventRequest:ii:", PPB_InputEvent_ClearInputEventRequestDispatcher }, + { "PPB_InputEvent_CreateMouseInputEvent:iidiiiii:i", PPB_InputEvent_CreateMouseInputEventDispatcher }, + { "PPB_InputEvent_CreateWheelInputEvent:ididdddi:i", PPB_InputEvent_CreateWheelInputEventDispatcher }, + { "PPB_InputEvent_CreateKeyboardInputEvent:iidiiC:i", PPB_InputEvent_CreateKeyboardInputEventDispatcher }, + { "PPB_Instance_BindGraphics:ii:i", PPB_Instance_BindGraphicsDispatcher }, + { "PPB_Instance_IsFullFrame:i:i", PPB_Instance_IsFullFrameDispatcher }, + { "PPB_Messaging_PostMessage:iC:", PPB_Messaging_PostMessageDispatcher }, + { "PPB_PDF_GetLocalizedString:ii:C", PPB_PDF_GetLocalizedStringDispatcher }, + { "PPB_PDF_GetResourceImage:ii:i", PPB_PDF_GetResourceImageDispatcher }, + { "PPB_PDF_GetFontFileWithFallback:iCCi:i", PPB_PDF_GetFontFileWithFallbackDispatcher }, + { "PPB_PDF_GetFontTableForPrivateFontFile:ii:Ci", PPB_PDF_GetFontTableForPrivateFontFileDispatcher }, + { "PPB_PDF_SearchString:iCCi:Ci", PPB_PDF_SearchStringDispatcher }, + { "PPB_PDF_DidStartLoading:i:", PPB_PDF_DidStartLoadingDispatcher }, + { "PPB_PDF_DidStopLoading:i:", PPB_PDF_DidStopLoadingDispatcher }, + { "PPB_PDF_SetContentRestriction:ii:", PPB_PDF_SetContentRestrictionDispatcher }, + { "PPB_PDF_HistogramPDFPageCount:i:", PPB_PDF_HistogramPDFPageCountDispatcher }, + { "PPB_PDF_UserMetricsRecordAction:C:", PPB_PDF_UserMetricsRecordActionDispatcher }, + { "PPB_PDF_HasUnsupportedFeature:i:", PPB_PDF_HasUnsupportedFeatureDispatcher }, + { "PPB_PDF_SaveAs:i:", PPB_PDF_SaveAsDispatcher }, + { "PPB_Scrollbar_Create:ii:i", PPB_Scrollbar_CreateDispatcher }, + { "PPB_Scrollbar_IsScrollbar:i:i", PPB_Scrollbar_IsScrollbarDispatcher }, + { "PPB_Scrollbar_IsOverlay:i:i", PPB_Scrollbar_IsOverlayDispatcher }, + { "PPB_Scrollbar_GetThickness:i:i", PPB_Scrollbar_GetThicknessDispatcher }, + { "PPB_Scrollbar_GetValue:i:i", PPB_Scrollbar_GetValueDispatcher }, + { "PPB_Scrollbar_SetValue:ii:", PPB_Scrollbar_SetValueDispatcher }, + { "PPB_Scrollbar_SetDocumentSize:ii:", PPB_Scrollbar_SetDocumentSizeDispatcher }, + { "PPB_Scrollbar_SetTickMarks:iCi:", PPB_Scrollbar_SetTickMarksDispatcher }, + { "PPB_Scrollbar_ScrollBy:iii:", PPB_Scrollbar_ScrollByDispatcher }, + { "PPB_Testing_ReadImageData:iiC:i", PPB_Testing_ReadImageDataDispatcher }, + { "PPB_Testing_RunMessageLoop:i:", PPB_Testing_RunMessageLoopDispatcher }, + { "PPB_Testing_QuitMessageLoop:i:", PPB_Testing_QuitMessageLoopDispatcher }, + { "PPB_Testing_GetLiveObjectsForInstance:i:i", PPB_Testing_GetLiveObjectsForInstanceDispatcher }, + { "PPB_URLLoader_Create:i:i", PPB_URLLoader_CreateDispatcher }, + { "PPB_URLLoader_IsURLLoader:i:i", PPB_URLLoader_IsURLLoaderDispatcher }, + { "PPB_URLLoader_Open:iii:i", PPB_URLLoader_OpenDispatcher }, + { "PPB_URLLoader_FollowRedirect:ii:i", PPB_URLLoader_FollowRedirectDispatcher }, + { "PPB_URLLoader_GetUploadProgress:i:lli", PPB_URLLoader_GetUploadProgressDispatcher }, + { "PPB_URLLoader_GetDownloadProgress:i:lli", PPB_URLLoader_GetDownloadProgressDispatcher }, + { "PPB_URLLoader_GetResponseInfo:i:i", PPB_URLLoader_GetResponseInfoDispatcher }, + { "PPB_URLLoader_ReadResponseBody:iii:Ci", PPB_URLLoader_ReadResponseBodyDispatcher }, + { "PPB_URLLoader_FinishStreamingToFile:ii:i", PPB_URLLoader_FinishStreamingToFileDispatcher }, + { "PPB_URLLoader_Close:i:", PPB_URLLoader_CloseDispatcher }, + { "PPB_URLRequestInfo_Create:i:i", PPB_URLRequestInfo_CreateDispatcher }, + { "PPB_URLRequestInfo_IsURLRequestInfo:i:i", PPB_URLRequestInfo_IsURLRequestInfoDispatcher }, + { "PPB_URLRequestInfo_SetProperty:iiC:i", PPB_URLRequestInfo_SetPropertyDispatcher }, + { "PPB_URLRequestInfo_AppendDataToBody:iC:i", PPB_URLRequestInfo_AppendDataToBodyDispatcher }, + { "PPB_URLRequestInfo_AppendFileToBody:iilld:i", PPB_URLRequestInfo_AppendFileToBodyDispatcher }, + { "PPB_URLResponseInfo_IsURLResponseInfo:i:i", PPB_URLResponseInfo_IsURLResponseInfoDispatcher }, + { "PPB_URLResponseInfo_GetProperty:ii:C", PPB_URLResponseInfo_GetPropertyDispatcher }, + { "PPB_URLResponseInfo_GetBodyAsFileRef:i:i", PPB_URLResponseInfo_GetBodyAsFileRefDispatcher }, + { "PPB_Widget_IsWidget:i:i", PPB_Widget_IsWidgetDispatcher }, + { "PPB_Widget_Paint:iCi:i", PPB_Widget_PaintDispatcher }, + { "PPB_Widget_HandleEvent:ii:i", PPB_Widget_HandleEventDispatcher }, + { "PPB_Widget_GetLocation:i:Ci", PPB_Widget_GetLocationDispatcher }, + { "PPB_Widget_SetLocation:iC:", PPB_Widget_SetLocationDispatcher }, + { "PPB_Zoom_ZoomChanged:id:", PPB_Zoom_ZoomChangedDispatcher }, + { "PPB_Zoom_ZoomLimitsChanged:idd:", PPB_Zoom_ZoomLimitsChangedDispatcher }, + { NULL, NULL } +}; + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppb_scrollbar.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppb_scrollbar.srpc new file mode 100644 index 0000000..3f01344 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppb_scrollbar.srpc @@ -0,0 +1,72 @@ +# 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. + +# RPC methods used to implement PPB_Scrollbar calls from the plugin. +# See ppapi/c/dev/ppb_scrollbar_dev.h for interface details. +{ + 'name': 'PpbScrollbarRpc', + 'rpcs': [ + {'name': 'PPB_Scrollbar_Create', + 'inputs': [['instance', 'PP_Instance'], + ['vertical', 'int32_t'], # PP_Bool + ], + 'outputs': [['scrollbar', 'PP_Resource'], + ] + }, + {'name': 'PPB_Scrollbar_IsScrollbar', + 'inputs': [['resource', 'PP_Resource'], + ], + 'outputs': [['is_scrollbar', 'int32_t'], # PP_Bool + ] + }, + {'name': 'PPB_Scrollbar_IsOverlay', + 'inputs': [['resource', 'PP_Resource'], + ], + 'outputs': [['is_overlay', 'int32_t'], # PP_Bool + ] + }, + {'name': 'PPB_Scrollbar_GetThickness', + 'inputs': [['resource', 'PP_Resource'], + ], + 'outputs': [['thickness', 'int32_t'], + ] + }, + {'name': 'PPB_Scrollbar_GetValue', + 'inputs': [['scrollbar', 'PP_Resource'], + ], + 'outputs': [['value', 'int32_t'], # uint32_t + ] + }, + {'name': 'PPB_Scrollbar_SetValue', + 'inputs': [['scrollbar', 'PP_Resource'], + ['value', 'int32_t'], # uint32_t + ], + 'outputs': [ + ] + }, + {'name': 'PPB_Scrollbar_SetDocumentSize', + 'inputs': [['scrollbar', 'PP_Resource'], + ['size', 'int32_t'], # uint32_t + ], + 'outputs': [ + ] + }, + {'name': 'PPB_Scrollbar_SetTickMarks', + 'inputs': [['scrollbar', 'PP_Resource'], + ['tick_marks', 'char[]'], # PP_Rect + ['count', 'int32_t'], # uint32_t + ], + 'outputs': [ + ] + }, + {'name': 'PPB_Scrollbar_ScrollBy', + 'inputs': [['scrollbar', 'PP_Resource'], + ['unit', 'int32_t'], # PP_ScrollBy_Dev + ['multiplier', 'int32_t'], + ], + 'outputs': [ + ] + }, + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppb_testing.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppb_testing.srpc new file mode 100644 index 0000000..305fffc --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppb_testing.srpc @@ -0,0 +1,37 @@ +# 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. + +# RPC methods used to implement PPB_Testing calls from the plugin. +# See ppapi/c/dev/ppb_testing_dev.h for interface details. +{ + 'name': 'PpbTestingRpc', + 'rpcs': [ + {'name': 'PPB_Testing_ReadImageData', + 'inputs': [['device_context_2d', 'PP_Resource'], + ['image', 'PP_Resource'], + ['top_left', 'char[]'], # PP_Point + ], + 'outputs': [['success', 'int32_t'], # PP_Bool + ] + }, + {'name': 'PPB_Testing_RunMessageLoop', + 'inputs': [['instance', 'PP_Instance'], + ], + 'outputs': [ + ] + }, + {'name': 'PPB_Testing_QuitMessageLoop', + 'inputs': [['instance', 'PP_Instance'], + ], + 'outputs': [ + ] + }, + {'name': 'PPB_Testing_GetLiveObjectsForInstance', + 'inputs': [['instance', 'PP_Instance'], + ], + 'outputs': [['live_object_count', 'int32_t'], # uint32_t + ] + }, + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppb_url_loader.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppb_url_loader.srpc new file mode 100644 index 0000000..ff7ba35 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppb_url_loader.srpc @@ -0,0 +1,83 @@ +# 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. +# +# RPC methods used to implement PPB_URLLoader calls from the plugin. +# See ppapi/c/ppb_url_loader.h for interface details. + +{ + 'name': 'PpbURLLoaderRpc', + 'rpcs': [ + {'name': 'PPB_URLLoader_Create', + 'inputs': [['instance', 'PP_Instance'], # PP_Instance + ], + 'outputs': [['resource', 'PP_Resource'], # PP_Resource + ] + }, + {'name': 'PPB_URLLoader_IsURLLoader', + 'inputs': [['resource', 'PP_Resource'], # PP_Resource + ], + 'outputs': [['is_url_loader', 'int32_t'], # PP_Bool + ] + }, + {'name': 'PPB_URLLoader_Open', + 'inputs': [['loader', 'PP_Resource'], # PP_Resource + ['request', 'PP_Resource'], # PP_Resource + ['callback_id', 'int32_t'], # PP_CompletionCallback + ], + 'outputs': [['pp_error', 'int32_t'], # int32_t + ] + }, + {'name': 'PPB_URLLoader_FollowRedirect', + 'inputs': [['loader', 'PP_Resource'], # PP_Resource + ['callback_id', 'int32_t'], # PP_CompletionCallback + ], + 'outputs': [['pp_error', 'int32_t'], # int32_t + ] + }, + {'name': 'PPB_URLLoader_GetUploadProgress', + 'inputs': [['loader', 'PP_Resource'], # PP_Resource + ], + 'outputs': [['bytes_sent', 'int64_t'], # int64_t* + ['total_bytes_to_be_sent', 'int64_t'], # int64_t* + ['success', 'int32_t'], # PP_Bool + ] + }, + {'name': 'PPB_URLLoader_GetDownloadProgress', + 'inputs': [['loader', 'PP_Resource'], # PP_Resource + ], + 'outputs': [['bytes_received', 'int64_t'], # int64_t* + ['total_bytes_to_be_received', 'int64_t'], # int64_t* + ['success', 'int32_t'], # PP_Bool + ] + }, + {'name': 'PPB_URLLoader_GetResponseInfo', + 'inputs': [['loader', 'PP_Resource'], # PP_Resource + ], + 'outputs': [['response', 'PP_Resource'], # PP_Resource + ] + }, + {'name': 'PPB_URLLoader_ReadResponseBody', + 'inputs': [['loader', 'PP_Resource'], # PP_Resource + ['bytes_to_read', 'int32_t'], # int32_t + ['callback_id', 'int32_t'], # PP_CompletionCallback + ], + 'outputs': [['buffer', 'char[]'], # char* + ['pp_error_or_bytes', 'int32_t'], # int32_t + ] + }, + {'name': 'PPB_URLLoader_FinishStreamingToFile', + 'inputs': [['loader', 'PP_Resource'], # PP_Resource + ['callback_id', 'int32_t'], # PP_CompletionCallback + ], + 'outputs': [['pp_error', 'int32_t'], # int32_t + ] + }, + {'name': 'PPB_URLLoader_Close', + 'inputs': [['loader', 'PP_Resource'], # PP_Resource + ], + 'outputs': [ + ] + }, + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppb_url_request_info.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppb_url_request_info.srpc new file mode 100644 index 0000000..91964bf --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppb_url_request_info.srpc @@ -0,0 +1,49 @@ +# Copyright (c) 2010 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. +# +# RPC methods used to implement PPB_URLRequestInfo calls from the plugin. +# See ppapi/c/ppb_url_request_info.h for interface details. + +{ + 'name': 'PpbURLRequestInfoRpc', + 'rpcs': [ + {'name': 'PPB_URLRequestInfo_Create', + 'inputs': [['instance', 'PP_Instance'], # PP_Instance + ], + 'outputs': [['resource', 'PP_Resource'], # PP_Resource + ] + }, + {'name': 'PPB_URLRequestInfo_IsURLRequestInfo', + 'inputs': [['resource', 'PP_Resource'], # PP_Resource + ], + 'outputs': [['success', 'int32_t'], # PP_Bool + ] + }, + {'name': 'PPB_URLRequestInfo_SetProperty', + 'inputs': [['request', 'PP_Resource'], # PP_Resource + ['property', 'int32_t'], # PP_URLRequestProperty + ['value', 'char[]'], # PP_Var + ], + 'outputs': [['success', 'int32_t'], # PP_Bool + ] + }, + {'name': 'PPB_URLRequestInfo_AppendDataToBody', + 'inputs': [['request', 'PP_Resource'], # PP_Resource + ['data', 'char[]'], # char* + uint32_t + ], + 'outputs': [['success', 'int32_t'], # PP_Bool + ] + }, + {'name': 'PPB_URLRequestInfo_AppendFileToBody', + 'inputs': [['request', 'PP_Resource'], # PP_Resource + ['file_ref', 'PP_Resource'], # PP_Resource + ['start_offset', 'int64_t'], # int64_t + ['number_of_bytes', 'int64_t'], # int64_t + ['expected_last_modified_time', 'double'], # PP_Time + ], + 'outputs': [['success', 'int32_t'], # PP_Bool + ] + }, + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppb_url_response_info.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppb_url_response_info.srpc new file mode 100644 index 0000000..47a9f4a --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppb_url_response_info.srpc @@ -0,0 +1,31 @@ +# Copyright (c) 2010 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. +# +# RPC methods used to implement PPB_URLResponseInfo calls from the plugin. +# See ppapi/c/ppb_url_response_info.h for interface details. + +{ + 'name': 'PpbURLResponseInfoRpc', + 'rpcs': [ + {'name': 'PPB_URLResponseInfo_IsURLResponseInfo', + 'inputs': [['resource', 'PP_Resource'], # PP_Resource + ], + 'outputs': [['success', 'int32_t'], # PP_Bool + ] + }, + {'name': 'PPB_URLResponseInfo_GetProperty', + 'inputs': [['response', 'PP_Resource'], # PP_Resource + ['property', 'int32_t'], # PP_URLResponseProperty + ], + 'outputs': [['value', 'char[]'], # PP_Var + ] + }, + {'name': 'PPB_URLResponseInfo_GetBodyAsFileRef', + 'inputs': [['response', 'PP_Resource'], # PP_Resource + ], + 'outputs': [['file_ref', 'PP_Resource'], # PP_Resource + ] + }, + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppb_widget.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppb_widget.srpc new file mode 100644 index 0000000..fa9d0f7 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppb_widget.srpc @@ -0,0 +1,46 @@ +# 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. + +# RPC methods used to implement PPB_Widget calls from the plugin. +# See ppapi/c/dev/ppb_widget_dev.h for interface details. +{ + 'name': 'PpbWidgetRpc', + 'rpcs': [ + {'name': 'PPB_Widget_IsWidget', + 'inputs': [['resource', 'PP_Resource'], + ], + 'outputs': [['is_widget', 'int32_t'], # PP_Bool + ] + }, + {'name': 'PPB_Widget_Paint', + 'inputs': [['widget', 'PP_Resource'], + ['rect', 'char[]'], # PP_Rect + ['image', 'PP_Resource'], + ], + 'outputs': [['success', 'int32_t'], # PP_Bool + ] + }, + {'name': 'PPB_Widget_HandleEvent', + 'inputs': [['widget', 'PP_Resource'], + ['event', 'PP_Resource'], # PP_InputEvent + ], + 'outputs': [['handled', 'int32_t'], # PP_Bool + ] + }, + {'name': 'PPB_Widget_GetLocation', + 'inputs': [['widget', 'PP_Resource'], + ], + 'outputs': [['location', 'char[]'], # PP_Rect + ['visible', 'int32_t'], # PP_Bool + ] + }, + {'name': 'PPB_Widget_SetLocation', + 'inputs': [['widget', 'PP_Resource'], + ['location', 'char[]'], # PP_Rect + ], + 'outputs': [ + ] + }, + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppb_zoom.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppb_zoom.srpc new file mode 100644 index 0000000..5e88dc1 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppb_zoom.srpc @@ -0,0 +1,26 @@ +# 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. + +# RPC methods used to implement the PPB_Zoom interface. +# See ppapi/c/dev/ppb_zoom_dev.h for interface details. +{ + 'name': 'PpbZoomRpc', + 'rpcs': [ + {'name': 'PPB_Zoom_ZoomChanged', + 'inputs': [['instance', 'PP_Instance'], + ['factor', 'double'], + ], + 'outputs': [ + ] + }, + {'name': 'PPB_Zoom_ZoomLimitsChanged', + 'inputs': [['instance', 'PP_Instance'], + ['minimum_factor', 'double'], + ['maximum_factor', 'double'], + ], + 'outputs': [ + ] + }, + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppp.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppp.srpc new file mode 100755 index 0000000..9ce32e1 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppp.srpc @@ -0,0 +1,36 @@ +# Copyright (c) 2010 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. + +# This file declares the RPC methods used to implement PPAPI calls from +# the browser to the plugin. It implements the interface in ppapi/c/ppp.h. +{ + 'name': 'PppRpc', + 'rpcs': [ + # PPP_Initialize is called once to initialize the plugin. + # It is effectively a class initializer for the plugin type. + {'name': 'PPP_InitializeModule', + 'inputs': [['pid', 'int32_t'], + ['module', 'PP_Module'], + ['upcall_channel_desc', 'handle'], + ['service_description', 'string'], + ], + 'outputs': [['nacl_pid', 'int32_t'], + ['success', 'int32_t'], + ] + }, + # PPP_ShutdownModule stops the plugin. + {'name': 'PPP_ShutdownModule', + 'inputs': [], + 'outputs': [] + }, + # PPP_GetInterface checks whether the plugin exports a specified + # interface name. + {'name': 'PPP_GetInterface', + 'inputs': [['interface_name', 'string'], + ], + 'outputs': [['exports_interface_name', 'int32_t'], + ] + }, + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppp_audio.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppp_audio.srpc new file mode 100755 index 0000000..71d37e5 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppp_audio.srpc @@ -0,0 +1,21 @@ +# Copyright (c) 2010 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. + +# This file declares the RPC methods used to implement PPB_Audio +# calls from the browser. The functions are described in +# ppapi/c/ppb_audio.h. +{ + 'name': 'PppAudioRpc', + 'rpcs': [ + # Stream Created + {'name': 'PPP_Audio_StreamCreated', + 'inputs': [['instance', 'PP_Instance'], + ['out_shm', 'handle'], + ['out_shm_size', 'int32_t'], + ['out_socket', 'handle'], + ], + 'outputs': [], + }, + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppp_find.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppp_find.srpc new file mode 100644 index 0000000..94a603e --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppp_find.srpc @@ -0,0 +1,32 @@ +# 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. + +# RPC methods used to implement PPP_Find calls to the plugin. +# See ppapi/c/dev/ppp_find_dev.h for interface details. +{ + 'name': 'PppFindRpc', + 'rpcs': [ + {'name': 'PPP_Find_StartFind', + 'inputs': [['instance', 'PP_Instance'], + ['text', 'char[]'], + ['case_sensitive', 'int32_t'], # PP_Bool + ], + 'outputs': [['supports_find', 'int32_t'], # PP_Bool + ] + }, + {'name': 'PPP_Find_SelectFindResult', + 'inputs': [['instance', 'PP_Instance'], + ['forward', 'int32_t'], # PP_Bool + ], + 'outputs': [ + ] + }, + {'name': 'PPP_Find_StopFind', + 'inputs': [['instance', 'PP_Instance'], + ], + 'outputs': [ + ] + }, + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppp_input_event.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppp_input_event.srpc new file mode 100644 index 0000000..0b90212 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppp_input_event.srpc @@ -0,0 +1,20 @@ +# 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. + +# RPC methods used to implement the PPP_InputEvent interface. +# See ppapi/c/ppp_input_event.h for interface details. +{ + 'name': 'PppInputEventRpc', + 'rpcs': [ + {'name': 'PPP_InputEvent_HandleInputEvent', + 'inputs': [['instance', 'PP_Instance'], + ['resource', 'PP_Resource'], + ['event_data', 'char[]'], # InputEventData + ['character_text', 'char[]'] # character text + ], + 'outputs': [['handled', 'int32_t'] # PP_Bool + ] + }, + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppp_instance.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppp_instance.srpc new file mode 100755 index 0000000..f398643 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppp_instance.srpc @@ -0,0 +1,53 @@ +# 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. + +# RPC methods used to implement PPP_Instance interface. +# See ppapi/c/ppp_instance.h for interface details. +{ + 'name': 'PppInstanceRpc', + 'rpcs': [ + # Generic comment: PPAPI uses Did... apparently to indicate that the + # return value indicates the plugin successfully responded to the + # action requested. + # Sets the instance's parameters. + {'name': 'PPP_Instance_DidCreate', + 'inputs': [['instance', 'PP_Instance'], # PP_Instance + ['argc', 'int32_t'], # uint32_t + ['argn', 'char[]'], # char*[] + ['argv', 'char[]'], # char*[] + ], + 'outputs': [['success', 'int32_t'], # PP_Bool + ] + }, + # Deletes an instance of a plugin. + {'name': 'PPP_Instance_DidDestroy', + 'inputs': [['instance', 'PP_Instance'], # PP_Instance + ], + 'outputs': [] + }, + # Changes the position, size, or clipping rectangle of the instance. + {'name': 'PPP_Instance_DidChangeView', + 'inputs': [['instance', 'PP_Instance'], # PP_Instance + ['position', 'int32_t[]'], # PP_Rect* + ['clip', 'int32_t[]'], # PP_Rect* + ], + 'outputs': [] + }, + # Processes a bool indicating that the instance gained or lost focus. + {'name': 'PPP_Instance_DidChangeFocus', + 'inputs': [['instance', 'PP_Instance'], # PP_Instance + ['has_focus', 'bool'], # PP_Bool + ], + 'outputs': [] + }, + # Passes URL information to a full-frame instance. + {'name': 'PPP_Instance_HandleDocumentLoad', + 'inputs': [['instance', 'PP_Instance'], # PP_Instance + ['url_loader', 'PP_Resource'], # PP_Resource + ], + 'outputs': [['success', 'int32_t'], # PP_Bool + ] + }, + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppp_messaging.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppp_messaging.srpc new file mode 100644 index 0000000..5ffd800 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppp_messaging.srpc @@ -0,0 +1,17 @@ +# Copyright (c) 2010 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. + +# RPC methods used to implement PPP_Messaging interface. +# See ppapi/c/ppp_messaging.h for interface details. +{ + 'name': 'PppMessagingRpc', + 'rpcs': [ + {'name': 'PPP_Messaging_HandleMessage', + 'inputs': [['instance', 'PP_Instance'], # PP_Instance + ['message', 'char[]'], # PP_Var + ], + 'outputs': [] + }, + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppp_printing.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppp_printing.srpc new file mode 100644 index 0000000..e7aba2a --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppp_printing.srpc @@ -0,0 +1,39 @@ +# 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. + +# RPC methods used to implement PPP_Printing calls to the plugin. +# See ppapi/c/dev/ppp_printing_dev.h for interface details. +{ + 'name': 'PppPrintingRpc', + 'rpcs': [ + {'name': 'PPP_Printing_QuerySupportedFormats', + 'inputs': [['instance', 'PP_Instance'], + ], + 'outputs': [['formats', 'char[]'], # PP_PrintOutputFormat_Dev array + ['format_count', 'int32_t'], # uint32_t + ] + }, + {'name': 'PPP_Printing_Begin', + 'inputs': [['instance', 'PP_Instance'], + ['print_settings', 'char[]'], # PP_PrintSettings_Dev + ], + 'outputs': [['pages_required', 'int32_t'], + ] + }, + {'name': 'PPP_Printing_PrintPages', + 'inputs': [['instance', 'PP_Instance'], + ['page_ranges', 'char[]'], # PP_PrintPageNumberRange_Dev + ['page_range_count', 'int32_t'], # uint32_t + ], + 'outputs': [['image_data', 'PP_Resource'], + ] + }, + {'name': 'PPP_Printing_End', + 'inputs': [['instance', 'PP_Instance'], + ], + 'outputs': [ + ] + }, + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppp_rpc_client.cc b/ppapi/native_client/src/shared/ppapi_proxy/ppp_rpc_client.cc new file mode 100644 index 0000000..9de4ae6 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppp_rpc_client.cc @@ -0,0 +1,443 @@ +// 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. +// +// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING +// +// Automatically generated code. See srpcgen.py +// +// NaCl Simple Remote Procedure Call interface abstractions. + +#include "trusted/srpcgen/ppp_rpc.h" +#ifdef __native_client__ +#ifndef UNREFERENCED_PARAMETER +#define UNREFERENCED_PARAMETER(P) do { (void) P; } while (0) +#endif // UNREFERENCED_PARAMETER +#else +#include "native_client/src/include/portability.h" +#endif // __native_client__ +#include "native_client/src/shared/ppapi_proxy/browser_globals.h" +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_resource.h" + +NaClSrpcError CompletionCallbackRpcClient::RunCompletionCallback( + NaClSrpcChannel* channel, + int32_t callback_id, + int32_t result, + nacl_abi_size_t read_buffer_bytes, char* read_buffer) { + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "RunCompletionCallback:iiC:", + callback_id, + result, + read_buffer_bytes, read_buffer + ); + return retval; +} + +NaClSrpcError PppRpcClient::PPP_InitializeModule( + NaClSrpcChannel* channel, + int32_t pid, + PP_Module module, + NaClSrpcImcDescType upcall_channel_desc, + char* service_description, + int32_t* nacl_pid, + int32_t* success) { + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPP_InitializeModule:iihs:ii", + pid, + module, + upcall_channel_desc, + service_description, + nacl_pid, + success + ); + return retval; +} + +NaClSrpcError PppRpcClient::PPP_ShutdownModule( + NaClSrpcChannel* channel) { + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPP_ShutdownModule::" + ); + return retval; +} + +NaClSrpcError PppRpcClient::PPP_GetInterface( + NaClSrpcChannel* channel, + char* interface_name, + int32_t* exports_interface_name) { + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPP_GetInterface:s:i", + interface_name, + exports_interface_name + ); + return retval; +} + +NaClSrpcError PppAudioRpcClient::PPP_Audio_StreamCreated( + NaClSrpcChannel* channel, + PP_Instance instance, + NaClSrpcImcDescType out_shm, + int32_t out_shm_size, + NaClSrpcImcDescType out_socket) { + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPP_Audio_StreamCreated:ihih:", + instance, + out_shm, + out_shm_size, + out_socket + ); + if (retval == NACL_SRPC_RESULT_INTERNAL) + ppapi_proxy::CleanUpAfterDeadNexe(instance); + return retval; +} + +NaClSrpcError PppFindRpcClient::PPP_Find_StartFind( + NaClSrpcChannel* channel, + PP_Instance instance, + nacl_abi_size_t text_bytes, char* text, + int32_t case_sensitive, + int32_t* supports_find) { + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPP_Find_StartFind:iCi:i", + instance, + text_bytes, text, + case_sensitive, + supports_find + ); + if (retval == NACL_SRPC_RESULT_INTERNAL) + ppapi_proxy::CleanUpAfterDeadNexe(instance); + return retval; +} + +NaClSrpcError PppFindRpcClient::PPP_Find_SelectFindResult( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t forward) { + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPP_Find_SelectFindResult:ii:", + instance, + forward + ); + if (retval == NACL_SRPC_RESULT_INTERNAL) + ppapi_proxy::CleanUpAfterDeadNexe(instance); + return retval; +} + +NaClSrpcError PppFindRpcClient::PPP_Find_StopFind( + NaClSrpcChannel* channel, + PP_Instance instance) { + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPP_Find_StopFind:i:", + instance + ); + if (retval == NACL_SRPC_RESULT_INTERNAL) + ppapi_proxy::CleanUpAfterDeadNexe(instance); + return retval; +} + +NaClSrpcError PppInputEventRpcClient::PPP_InputEvent_HandleInputEvent( + NaClSrpcChannel* channel, + PP_Instance instance, + PP_Resource resource, + nacl_abi_size_t event_data_bytes, char* event_data, + nacl_abi_size_t character_text_bytes, char* character_text, + int32_t* handled) { + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPP_InputEvent_HandleInputEvent:iiCC:i", + instance, + resource, + event_data_bytes, event_data, + character_text_bytes, character_text, + handled + ); + if (retval == NACL_SRPC_RESULT_INTERNAL) + ppapi_proxy::CleanUpAfterDeadNexe(instance); + return retval; +} + +NaClSrpcError PppInstanceRpcClient::PPP_Instance_DidCreate( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t argc, + nacl_abi_size_t argn_bytes, char* argn, + nacl_abi_size_t argv_bytes, char* argv, + int32_t* success) { + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPP_Instance_DidCreate:iiCC:i", + instance, + argc, + argn_bytes, argn, + argv_bytes, argv, + success + ); + if (retval == NACL_SRPC_RESULT_INTERNAL) + ppapi_proxy::CleanUpAfterDeadNexe(instance); + return retval; +} + +NaClSrpcError PppInstanceRpcClient::PPP_Instance_DidDestroy( + NaClSrpcChannel* channel, + PP_Instance instance) { + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPP_Instance_DidDestroy:i:", + instance + ); + if (retval == NACL_SRPC_RESULT_INTERNAL) + ppapi_proxy::CleanUpAfterDeadNexe(instance); + return retval; +} + +NaClSrpcError PppInstanceRpcClient::PPP_Instance_DidChangeView( + NaClSrpcChannel* channel, + PP_Instance instance, + nacl_abi_size_t position_bytes, int32_t* position, + nacl_abi_size_t clip_bytes, int32_t* clip) { + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPP_Instance_DidChangeView:iII:", + instance, + position_bytes, position, + clip_bytes, clip + ); + if (retval == NACL_SRPC_RESULT_INTERNAL) + ppapi_proxy::CleanUpAfterDeadNexe(instance); + return retval; +} + +NaClSrpcError PppInstanceRpcClient::PPP_Instance_DidChangeFocus( + NaClSrpcChannel* channel, + PP_Instance instance, + bool has_focus) { + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPP_Instance_DidChangeFocus:ib:", + instance, + has_focus + ); + if (retval == NACL_SRPC_RESULT_INTERNAL) + ppapi_proxy::CleanUpAfterDeadNexe(instance); + return retval; +} + +NaClSrpcError PppInstanceRpcClient::PPP_Instance_HandleDocumentLoad( + NaClSrpcChannel* channel, + PP_Instance instance, + PP_Resource url_loader, + int32_t* success) { + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPP_Instance_HandleDocumentLoad:ii:i", + instance, + url_loader, + success + ); + if (retval == NACL_SRPC_RESULT_INTERNAL) + ppapi_proxy::CleanUpAfterDeadNexe(instance); + return retval; +} + +NaClSrpcError PppMessagingRpcClient::PPP_Messaging_HandleMessage( + NaClSrpcChannel* channel, + PP_Instance instance, + nacl_abi_size_t message_bytes, char* message) { + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPP_Messaging_HandleMessage:iC:", + instance, + message_bytes, message + ); + if (retval == NACL_SRPC_RESULT_INTERNAL) + ppapi_proxy::CleanUpAfterDeadNexe(instance); + return retval; +} + +NaClSrpcError PppPrintingRpcClient::PPP_Printing_QuerySupportedFormats( + NaClSrpcChannel* channel, + PP_Instance instance, + nacl_abi_size_t* formats_bytes, char* formats, + int32_t* format_count) { + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPP_Printing_QuerySupportedFormats:i:Ci", + instance, + formats_bytes, formats, + format_count + ); + if (retval == NACL_SRPC_RESULT_INTERNAL) + ppapi_proxy::CleanUpAfterDeadNexe(instance); + return retval; +} + +NaClSrpcError PppPrintingRpcClient::PPP_Printing_Begin( + NaClSrpcChannel* channel, + PP_Instance instance, + nacl_abi_size_t print_settings_bytes, char* print_settings, + int32_t* pages_required) { + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPP_Printing_Begin:iC:i", + instance, + print_settings_bytes, print_settings, + pages_required + ); + if (retval == NACL_SRPC_RESULT_INTERNAL) + ppapi_proxy::CleanUpAfterDeadNexe(instance); + return retval; +} + +NaClSrpcError PppPrintingRpcClient::PPP_Printing_PrintPages( + NaClSrpcChannel* channel, + PP_Instance instance, + nacl_abi_size_t page_ranges_bytes, char* page_ranges, + int32_t page_range_count, + PP_Resource* image_data) { + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPP_Printing_PrintPages:iCi:i", + instance, + page_ranges_bytes, page_ranges, + page_range_count, + image_data + ); + if (retval == NACL_SRPC_RESULT_INTERNAL) + ppapi_proxy::CleanUpAfterDeadNexe(instance); + return retval; +} + +NaClSrpcError PppPrintingRpcClient::PPP_Printing_End( + NaClSrpcChannel* channel, + PP_Instance instance) { + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPP_Printing_End:i:", + instance + ); + if (retval == NACL_SRPC_RESULT_INTERNAL) + ppapi_proxy::CleanUpAfterDeadNexe(instance); + return retval; +} + +NaClSrpcError PppScrollbarRpcClient::PPP_Scrollbar_ValueChanged( + NaClSrpcChannel* channel, + PP_Instance instance, + PP_Resource scrollbar, + int32_t value) { + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPP_Scrollbar_ValueChanged:iii:", + instance, + scrollbar, + value + ); + if (retval == NACL_SRPC_RESULT_INTERNAL) + ppapi_proxy::CleanUpAfterDeadNexe(instance); + return retval; +} + +NaClSrpcError PppScrollbarRpcClient::PPP_Scrollbar_OverlayChanged( + NaClSrpcChannel* channel, + PP_Instance instance, + PP_Resource scrollbar, + int32_t overlay) { + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPP_Scrollbar_OverlayChanged:iii:", + instance, + scrollbar, + overlay + ); + if (retval == NACL_SRPC_RESULT_INTERNAL) + ppapi_proxy::CleanUpAfterDeadNexe(instance); + return retval; +} + +NaClSrpcError PppSelectionRpcClient::PPP_Selection_GetSelectedText( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t html, + nacl_abi_size_t* selected_text_bytes, char* selected_text) { + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPP_Selection_GetSelectedText:ii:C", + instance, + html, + selected_text_bytes, selected_text + ); + if (retval == NACL_SRPC_RESULT_INTERNAL) + ppapi_proxy::CleanUpAfterDeadNexe(instance); + return retval; +} + +NaClSrpcError PppWidgetRpcClient::PPP_Widget_Invalidate( + NaClSrpcChannel* channel, + PP_Instance instance, + PP_Resource widget, + nacl_abi_size_t dirty_rect_bytes, char* dirty_rect) { + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPP_Widget_Invalidate:iiC:", + instance, + widget, + dirty_rect_bytes, dirty_rect + ); + if (retval == NACL_SRPC_RESULT_INTERNAL) + ppapi_proxy::CleanUpAfterDeadNexe(instance); + return retval; +} + +NaClSrpcError PppZoomRpcClient::PPP_Zoom_Zoom( + NaClSrpcChannel* channel, + PP_Instance instance, + double factor, + int32_t text_only) { + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPP_Zoom_Zoom:idi:", + instance, + factor, + text_only + ); + if (retval == NACL_SRPC_RESULT_INTERNAL) + ppapi_proxy::CleanUpAfterDeadNexe(instance); + return retval; +} + + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppp_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/ppp_rpc_server.cc new file mode 100644 index 0000000..b420d78 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppp_rpc_server.cc @@ -0,0 +1,427 @@ +// 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. +// +// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING +// +// Automatically generated code. See srpcgen.py +// +// NaCl Simple Remote Procedure Call interface abstractions. + +#include "untrusted/srpcgen/ppp_rpc.h" +#ifdef __native_client__ +#ifndef UNREFERENCED_PARAMETER +#define UNREFERENCED_PARAMETER(P) do { (void) P; } while (0) +#endif // UNREFERENCED_PARAMETER +#else +#include "native_client/src/include/portability.h" +#endif // __native_client__ +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_resource.h" + +namespace { + +static void RunCompletionCallbackDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + CompletionCallbackRpcServer::RunCompletionCallback( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + inputs[2]->u.count, inputs[2]->arrays.carr + ); +} + +static void PPP_InitializeModuleDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PppRpcServer::PPP_InitializeModule( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + inputs[2]->u.hval, + inputs[3]->arrays.str, + &(outputs[0]->u.ival), + &(outputs[1]->u.ival) + ); +} + +static void PPP_ShutdownModuleDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(inputs); + UNREFERENCED_PARAMETER(outputs); + PppRpcServer::PPP_ShutdownModule( + rpc, + done + ); +} + +static void PPP_GetInterfaceDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PppRpcServer::PPP_GetInterface( + rpc, + done, + inputs[0]->arrays.str, + &(outputs[0]->u.ival) + ); +} + +static void PPP_Audio_StreamCreatedDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PppAudioRpcServer::PPP_Audio_StreamCreated( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.hval, + inputs[2]->u.ival, + inputs[3]->u.hval + ); +} + +static void PPP_Find_StartFindDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PppFindRpcServer::PPP_Find_StartFind( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.count, inputs[1]->arrays.carr, + inputs[2]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPP_Find_SelectFindResultDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PppFindRpcServer::PPP_Find_SelectFindResult( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival + ); +} + +static void PPP_Find_StopFindDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PppFindRpcServer::PPP_Find_StopFind( + rpc, + done, + inputs[0]->u.ival + ); +} + +static void PPP_InputEvent_HandleInputEventDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PppInputEventRpcServer::PPP_InputEvent_HandleInputEvent( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + inputs[2]->u.count, inputs[2]->arrays.carr, + inputs[3]->u.count, inputs[3]->arrays.carr, + &(outputs[0]->u.ival) + ); +} + +static void PPP_Instance_DidCreateDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PppInstanceRpcServer::PPP_Instance_DidCreate( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + inputs[2]->u.count, inputs[2]->arrays.carr, + inputs[3]->u.count, inputs[3]->arrays.carr, + &(outputs[0]->u.ival) + ); +} + +static void PPP_Instance_DidDestroyDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PppInstanceRpcServer::PPP_Instance_DidDestroy( + rpc, + done, + inputs[0]->u.ival + ); +} + +static void PPP_Instance_DidChangeViewDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PppInstanceRpcServer::PPP_Instance_DidChangeView( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.count, inputs[1]->arrays.iarr, + inputs[2]->u.count, inputs[2]->arrays.iarr + ); +} + +static void PPP_Instance_DidChangeFocusDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PppInstanceRpcServer::PPP_Instance_DidChangeFocus( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.bval + ); +} + +static void PPP_Instance_HandleDocumentLoadDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PppInstanceRpcServer::PPP_Instance_HandleDocumentLoad( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPP_Messaging_HandleMessageDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PppMessagingRpcServer::PPP_Messaging_HandleMessage( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.count, inputs[1]->arrays.carr + ); +} + +static void PPP_Printing_QuerySupportedFormatsDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PppPrintingRpcServer::PPP_Printing_QuerySupportedFormats( + rpc, + done, + inputs[0]->u.ival, + &(outputs[0]->u.count), outputs[0]->arrays.carr, + &(outputs[1]->u.ival) + ); +} + +static void PPP_Printing_BeginDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PppPrintingRpcServer::PPP_Printing_Begin( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.count, inputs[1]->arrays.carr, + &(outputs[0]->u.ival) + ); +} + +static void PPP_Printing_PrintPagesDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PppPrintingRpcServer::PPP_Printing_PrintPages( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.count, inputs[1]->arrays.carr, + inputs[2]->u.ival, + &(outputs[0]->u.ival) + ); +} + +static void PPP_Printing_EndDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PppPrintingRpcServer::PPP_Printing_End( + rpc, + done, + inputs[0]->u.ival + ); +} + +static void PPP_Scrollbar_ValueChangedDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PppScrollbarRpcServer::PPP_Scrollbar_ValueChanged( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + inputs[2]->u.ival + ); +} + +static void PPP_Scrollbar_OverlayChangedDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PppScrollbarRpcServer::PPP_Scrollbar_OverlayChanged( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + inputs[2]->u.ival + ); +} + +static void PPP_Selection_GetSelectedTextDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + PppSelectionRpcServer::PPP_Selection_GetSelectedText( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + &(outputs[0]->u.count), outputs[0]->arrays.carr + ); +} + +static void PPP_Widget_InvalidateDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PppWidgetRpcServer::PPP_Widget_Invalidate( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + inputs[2]->u.count, inputs[2]->arrays.carr + ); +} + +static void PPP_Zoom_ZoomDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PppZoomRpcServer::PPP_Zoom_Zoom( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.dval, + inputs[2]->u.ival + ); +} + +} // namespace + +NaClSrpcHandlerDesc PppRpcs::srpc_methods[] = { + { "RunCompletionCallback:iiC:", RunCompletionCallbackDispatcher }, + { "PPP_InitializeModule:iihs:ii", PPP_InitializeModuleDispatcher }, + { "PPP_ShutdownModule::", PPP_ShutdownModuleDispatcher }, + { "PPP_GetInterface:s:i", PPP_GetInterfaceDispatcher }, + { "PPP_Audio_StreamCreated:ihih:", PPP_Audio_StreamCreatedDispatcher }, + { "PPP_Find_StartFind:iCi:i", PPP_Find_StartFindDispatcher }, + { "PPP_Find_SelectFindResult:ii:", PPP_Find_SelectFindResultDispatcher }, + { "PPP_Find_StopFind:i:", PPP_Find_StopFindDispatcher }, + { "PPP_InputEvent_HandleInputEvent:iiCC:i", PPP_InputEvent_HandleInputEventDispatcher }, + { "PPP_Instance_DidCreate:iiCC:i", PPP_Instance_DidCreateDispatcher }, + { "PPP_Instance_DidDestroy:i:", PPP_Instance_DidDestroyDispatcher }, + { "PPP_Instance_DidChangeView:iII:", PPP_Instance_DidChangeViewDispatcher }, + { "PPP_Instance_DidChangeFocus:ib:", PPP_Instance_DidChangeFocusDispatcher }, + { "PPP_Instance_HandleDocumentLoad:ii:i", PPP_Instance_HandleDocumentLoadDispatcher }, + { "PPP_Messaging_HandleMessage:iC:", PPP_Messaging_HandleMessageDispatcher }, + { "PPP_Printing_QuerySupportedFormats:i:Ci", PPP_Printing_QuerySupportedFormatsDispatcher }, + { "PPP_Printing_Begin:iC:i", PPP_Printing_BeginDispatcher }, + { "PPP_Printing_PrintPages:iCi:i", PPP_Printing_PrintPagesDispatcher }, + { "PPP_Printing_End:i:", PPP_Printing_EndDispatcher }, + { "PPP_Scrollbar_ValueChanged:iii:", PPP_Scrollbar_ValueChangedDispatcher }, + { "PPP_Scrollbar_OverlayChanged:iii:", PPP_Scrollbar_OverlayChangedDispatcher }, + { "PPP_Selection_GetSelectedText:ii:C", PPP_Selection_GetSelectedTextDispatcher }, + { "PPP_Widget_Invalidate:iiC:", PPP_Widget_InvalidateDispatcher }, + { "PPP_Zoom_Zoom:idi:", PPP_Zoom_ZoomDispatcher }, + { NULL, NULL } +}; + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppp_scrollbar.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppp_scrollbar.srpc new file mode 100644 index 0000000..528ac04 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppp_scrollbar.srpc @@ -0,0 +1,27 @@ +# 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. + +# RPC methods used to implement PPP_Scrollbar calls to the plugin. +# See ppapi/c/dev/ppp_scrollbar_dev.h for interface details. +{ + 'name': 'PppScrollbarRpc', + 'rpcs': [ + {'name': 'PPP_Scrollbar_ValueChanged', + 'inputs': [['instance', 'PP_Instance'], + ['scrollbar', 'PP_Resource'], + ['value', 'int32_t'], # uint32_t + ], + 'outputs': [ + ] + }, + {'name': 'PPP_Scrollbar_OverlayChanged', + 'inputs': [['instance', 'PP_Instance'], + ['scrollbar', 'PP_Resource'], + ['overlay', 'int32_t'], # PP_Bool + ], + 'outputs': [ + ] + }, + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppp_selection.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppp_selection.srpc new file mode 100644 index 0000000..75d52fb --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppp_selection.srpc @@ -0,0 +1,18 @@ +# 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. + +# RPC methods used to implement PPP_Selection calls to the plugin. +# See ppapi/c/dev/ppp_selection_dev.h for interface details. +{ + 'name': 'PppSelectionRpc', + 'rpcs': [ + {'name': 'PPP_Selection_GetSelectedText', + 'inputs': [['instance', 'PP_Instance'], + ['html', 'int32_t'], # PP_Bool + ], + 'outputs': [['selected_text', 'char[]'], # PP_Var + ], + }, + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppp_widget.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppp_widget.srpc new file mode 100644 index 0000000..755f8c8 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppp_widget.srpc @@ -0,0 +1,19 @@ +# 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. + +# RPC methods used to implement PPP_Widget calls to the plugin. +# See ppapi/c/dev/ppp_widget_dev.h for interface details. +{ + 'name': 'PppWidgetRpc', + 'rpcs': [ + {'name': 'PPP_Widget_Invalidate', + 'inputs': [['instance', 'PP_Instance'], + ['widget', 'PP_Resource'], + ['dirty_rect', 'char[]'], # PP_Rect + ], + 'outputs': [ + ] + }, + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppp_zoom.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppp_zoom.srpc new file mode 100644 index 0000000..f9d01c3 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppp_zoom.srpc @@ -0,0 +1,19 @@ +# 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. + +# RPC methods used to implement PPP_Zoom calls to the plugin. +# See ppapi/c/dev/ppp_zoom_dev.h for interface details. +{ + 'name': 'PppZoomRpc', + 'rpcs': [ + {'name': 'PPP_Zoom_Zoom', + 'inputs': [['instance', 'PP_Instance'], + ['factor', 'double'], + ['text_only', 'int32_t'], # PP_Bool + ], + 'outputs': [ + ] + }, + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppruntime.h b/ppapi/native_client/src/shared/ppapi_proxy/ppruntime.h new file mode 100644 index 0000000..6852ad3 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppruntime.h @@ -0,0 +1,30 @@ +/* + * 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. + */ + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PPRUNTIME_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PPRUNTIME_H_ + +#include "native_client/src/include/portability.h" +#include "native_client/src/untrusted/irt/irt_ppapi.h" + +EXTERN_C_BEGIN + +// Initialize srpc connection to the browser. Some APIs like manifest file +// opening do not need full ppapi initialization and so can be used after +// this function returns. +int IrtInit(); + +// The entry point for the main thread of the PPAPI plugin process. +int PpapiPluginMain(); + +void PpapiPluginRegisterThreadCreator( + const struct PP_ThreadFunctions* new_funcs); + +void PpapiPluginRegisterDefaultThreadCreator(); + +EXTERN_C_END + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PPRUNTIME_H_ diff --git a/ppapi/native_client/src/shared/ppapi_proxy/proxy_var.cc b/ppapi/native_client/src/shared/ppapi_proxy/proxy_var.cc new file mode 100644 index 0000000..aec9bc5 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/proxy_var.cc @@ -0,0 +1,30 @@ +// 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/proxy_var.h" + +#include "native_client/src/shared/platform/nacl_sync_checked.h" +#include "native_client/src/untrusted/pthread/pthread.h" + +#include <limits> + +namespace ppapi_proxy { + +namespace { + +pthread_mutex_t mu = PTHREAD_MUTEX_INITIALIZER; + +} // namespace + +int64_t ProxyVar::unique_var_id = 0; + +ProxyVar::ProxyVar(PP_VarType pp_var_type) : pp_var_type_(pp_var_type) { + // Roll id of INT64_MAX to 1, because an id of 0 is not valid. + nacl::ScopedPthreadMutexLock ml(&mu); + if (unique_var_id > std::numeric_limits<int64_t>::max() - 1) + unique_var_id = 0; + id_ = ++unique_var_id; +} + +} // namespace ppapi_proxy diff --git a/ppapi/native_client/src/shared/ppapi_proxy/proxy_var.h b/ppapi/native_client/src/shared/ppapi_proxy/proxy_var.h new file mode 100644 index 0000000..bbf70a4 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/proxy_var.h @@ -0,0 +1,56 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PROXY_VAR_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PROXY_VAR_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/nacl_memory.h" +#include "native_client/src/include/ref_counted.h" +#include "ppapi/c/pp_var.h" + +namespace ppapi_proxy { + +// Complex PP_Var types (such as strings) have a copy of the variant's contents +// cached by the proxy. This is done so that PP_Vars can be reference counted, +// and their contents accessed "locally" by NaCl modules without having to +// perform a complete round trip to the browser for each such operation. +// +// Note: this class is intended to be sub-classed to handle specific content +// types such as strings, dictionaries, or arrays. +class ProxyVar : public nacl::RefCounted<ProxyVar> { + public: + // The type of this cached object. Simple types (int, bool, etc.) are not + // cached. + PP_VarType pp_var_type() const { return pp_var_type_; } + + // The assigned unique id associated with this object. Use this as the id + // for the corresponding PP_Var. + int64_t id() const { return id_; } + + protected: + // Initialize this instance to represent a PP_Var of type |pp_var_type|. + // Generates a unique id for this instance, and sets the reference count to 1. + // Subclasses should implement ctors that handle specific content data. + explicit ProxyVar(PP_VarType pp_var_type); + + virtual ~ProxyVar() {} + + private: + friend class nacl::RefCounted<ProxyVar>; + PP_VarType pp_var_type_; + int64_t id_; + + ProxyVar(); // Not implemented - do not use. + NACL_DISALLOW_COPY_AND_ASSIGN(ProxyVar); + + // A counter for unique ids. + static int64_t unique_var_id; +}; + +typedef scoped_refptr<ProxyVar> SharedProxyVar; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PROXY_VAR_H_ diff --git a/ppapi/native_client/src/shared/ppapi_proxy/proxy_var_cache.cc b/ppapi/native_client/src/shared/ppapi_proxy/proxy_var_cache.cc new file mode 100644 index 0000000..d990c2c --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/proxy_var_cache.cc @@ -0,0 +1,89 @@ +// 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/proxy_var_cache.h" + +#include <limits> +#include <map> + +#include "native_client/src/include/ref_counted.h" +#include "native_client/src/untrusted/pthread/pthread.h" + +namespace ppapi_proxy { + +namespace { + +pthread_mutex_t mu = PTHREAD_MUTEX_INITIALIZER; + +} // namespace + +ProxyVarCache* ProxyVarCache::cache_singleton = NULL; + +ProxyVarCache& ProxyVarCache::GetInstance() { + // When the deprecated scripting is removed, this crash should disappear. + // static ProxyVarCache cache_singleton; + // return cache_singleton; + pthread_mutex_lock(&mu); + if (cache_singleton == NULL) + cache_singleton = new ProxyVarCache(); + pthread_mutex_unlock(&mu); + return *cache_singleton; +} + +void ProxyVarCache::RetainSharedProxyVar(const SharedProxyVar& proxy_var) { + pthread_mutex_lock(&mu); + // This implements "insert if absent, retain if present". + std::pair<ProxyVarDictionary::iterator, bool> insert_result = + proxy_var_cache_.insert( + std::pair<int64_t, SharedProxyVar>(proxy_var->id(), proxy_var)); + if (!insert_result.second) { + // Object already exists, bump the retain count. + insert_result.first->second->AddRef(); + } + pthread_mutex_unlock(&mu); +} + +void ProxyVarCache::RetainProxyVar(const PP_Var& var) { + if (!IsCachedType(var)) + return; + pthread_mutex_lock(&mu); + ProxyVarDictionary::iterator iter = proxy_var_cache_.find(var.value.as_id); + if (iter != proxy_var_cache_.end()) { + iter->second->AddRef(); + } + pthread_mutex_unlock(&mu); +} + +void ProxyVarCache::ReleaseProxyVar(const PP_Var& var) { + if (!IsCachedType(var)) + return; + pthread_mutex_lock(&mu); + ProxyVarDictionary::iterator iter = proxy_var_cache_.find(var.value.as_id); + if (iter != proxy_var_cache_.end()) { + // Decrement the reference count by one, as requested. + iter->second->Release(); + // All var reference count updating happens while mu is held, so the + // potential race between HasOneRef and AddRef/Release cannot materialize. + if (iter->second->HasOneRef()) { + // If there is only one reference, it must be from the dictionary. + // Delete the dictionary entry. + proxy_var_cache_.erase(iter); + } + } + pthread_mutex_unlock(&mu); +} + +SharedProxyVar ProxyVarCache::SharedProxyVarForVar(PP_Var pp_var) const { + SharedProxyVar proxy_var; + pthread_mutex_lock(&mu); + ProxyVarDictionary::const_iterator iter = + proxy_var_cache_.find(pp_var.value.as_id); + if (iter != proxy_var_cache_.end()) { + proxy_var = iter->second; + } + pthread_mutex_unlock(&mu); + return proxy_var; +} + +} // namespace ppapi_proxy diff --git a/ppapi/native_client/src/shared/ppapi_proxy/proxy_var_cache.h b/ppapi/native_client/src/shared/ppapi_proxy/proxy_var_cache.h new file mode 100644 index 0000000..7836854 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/proxy_var_cache.h @@ -0,0 +1,73 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PROXY_VAR_CACHE_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PROXY_VAR_CACHE_H_ + +#include <map> + +#include "native_client/src/include/nacl_memory.h" +#include "native_client/src/shared/ppapi_proxy/proxy_var.h" +#include "ppapi/c/pp_var.h" + +namespace ppapi_proxy { + +// This class manages the proxy-local cache of ProxyVars. The base factory +// method generates a unique id that gets used as the PP_Var's id, this id is +// associated with the variant's content. The factory also inserts the new +// instance into the proxy-local cache. +// Note: There is one proxy var cache per NaCl module instance. +class ProxyVarCache { + public: + // Return the global proxy var cache. Always returns a valid (possibly + // empty) cache. + static ProxyVarCache& GetInstance(); + + // If |proxy_var| already exists in the cache, then increment its reference + // count. Otherwise, add it to the cache. This method does not check the + // validity of |proxy_var|, assuming that it's not possible to make a + // SharedProxyVar unless you use one of the cacheable subclasses. + // TODO(dspringer): Should the contents of the proxy_var in the cache be + // replaced with |proxy_var|? Should there be some kind of assert if an + // object with the same id exists in the cache but the contents are different? + void RetainSharedProxyVar(const SharedProxyVar& proxy_var); + + // Find the proxy var associated with |id| and increment its ref count. Does + // nothing if no such object exists. This only operates on vars that are + // cached (that is, IsCachedType() returns |true|). Any other var type is + // not cached, and this function does nothing. + void RetainProxyVar(const PP_Var& var); + + // Release the cached object associated with |id|. If the reference count + // of the object falls to 0, it gets removed from the cache. This only + // operates on vars that are cached (that is, IsCachedType() returns |true|). + // Any other var type is ignored, and this function does nothing. + void ReleaseProxyVar(const PP_Var& var); + + // Find the object in the cache associated with |pp_var|. + SharedProxyVar SharedProxyVarForVar(PP_Var pp_var) const; + + private: + // Return whether or not a var type is cached. + // Note to implementers: be sure to add to this function when adding new + // cached types. + // TODO(dspringer): When all the complex var types are handled, this + // test can turn into something like var.type >= PP_VARTYPE_STRING. + bool IsCachedType(const PP_Var& var) { + return var.type == PP_VARTYPE_STRING || var.type == PP_VARTYPE_OBJECT; + } + + // The cache of these objects. The value is a shared pointer so that + // instances of subclasses can be inserted. + typedef std::map<int64_t, SharedProxyVar> ProxyVarDictionary; + ProxyVarDictionary proxy_var_cache_; + + static ProxyVarCache* cache_singleton; + + ProxyVarCache() {} +}; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PROXY_VAR_CACHE_H_ diff --git a/ppapi/native_client/src/shared/ppapi_proxy/string_proxy_var.h b/ppapi/native_client/src/shared/ppapi_proxy/string_proxy_var.h new file mode 100644 index 0000000..dc7ab0e --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/string_proxy_var.h @@ -0,0 +1,48 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_STRING_PROXY_VAR_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_STRING_PROXY_VAR_H_ + +#include "native_client/src/include/nacl_memory.h" +#include "native_client/src/shared/ppapi_proxy/proxy_var.h" + +#include <string> + +namespace ppapi_proxy { + +// Subclass of ProxyVar that handles string objects. +class StringProxyVar : public ProxyVar { + public: + explicit StringProxyVar(const std::string& contents) + : ProxyVar(PP_VARTYPE_STRING), contents_(contents) {} + + StringProxyVar(const char* data, size_t len) + : ProxyVar(PP_VARTYPE_STRING), contents_(data, len) {} + + const std::string& contents() const { return contents_; } + + // Convenience function to do type checking and down-casting. This returns a + // scoped_refptr<>, so you don't have to down-cast the raw pointer. + static scoped_refptr<StringProxyVar> CastFromProxyVar( + SharedProxyVar proxy_var) { + if (proxy_var == NULL || proxy_var->pp_var_type() != PP_VARTYPE_STRING) { + scoped_refptr<StringProxyVar> string_var; + return string_var; + } + return scoped_refptr<StringProxyVar>( + static_cast<StringProxyVar*>(proxy_var.get())); + } + + private: + std::string contents_; + + StringProxyVar(); // Not implemented, do not use. +}; + +typedef scoped_refptr<StringProxyVar> SharedStringProxyVar; + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_STRING_PROXY_VAR_H_ diff --git a/ppapi/native_client/src/shared/ppapi_proxy/trusted/srpcgen/ppb_rpc.h b/ppapi/native_client/src/shared/ppapi_proxy/trusted/srpcgen/ppb_rpc.h new file mode 100644 index 0000000..274c548 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/trusted/srpcgen/ppb_rpc.h @@ -0,0 +1,1105 @@ +// 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. +// +// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING +// +// Automatically generated code. See srpcgen.py +// +// NaCl Simple Remote Procedure Call interface abstractions. + +#ifndef GEN_PPAPI_PROXY_PPB_RPC_H_ +#define GEN_PPAPI_PROXY_PPB_RPC_H_ + +#ifndef __native_client__ +#include "native_client/src/include/portability.h" +#endif // __native_client__ +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_resource.h" + +class NaClFileRpcServer { + public: + static void StreamAsFile( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + char* url, + int32_t callback_id); + static void GetFileDesc( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + char* url, + NaClSrpcImcDescType* file_desc); + + private: + NaClFileRpcServer(); + NaClFileRpcServer(const NaClFileRpcServer&); + void operator=(const NaClFileRpcServer); +}; // class NaClFileRpcServer + +class PpbRpcServer { + public: + static void PPB_GetInterface( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + char* interface_name, + int32_t* exports_interface_name); + + private: + PpbRpcServer(); + PpbRpcServer(const PpbRpcServer&); + void operator=(const PpbRpcServer); +}; // class PpbRpcServer + +class PpbAudioRpcServer { + public: + static void PPB_Audio_Create( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + PP_Resource config, + PP_Resource* out_resource); + static void PPB_Audio_IsAudio( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* out_bool); + static void PPB_Audio_GetCurrentConfig( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + PP_Resource* out_resource); + static void PPB_Audio_StopPlayback( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* out_bool); + static void PPB_Audio_StartPlayback( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* out_bool); + + private: + PpbAudioRpcServer(); + PpbAudioRpcServer(const PpbAudioRpcServer&); + void operator=(const PpbAudioRpcServer); +}; // class PpbAudioRpcServer + +class PpbAudioConfigRpcServer { + public: + static void PPB_AudioConfig_CreateStereo16Bit( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t sample_rate, + int32_t sample_frame_count, + PP_Resource* resource); + static void PPB_AudioConfig_IsAudioConfig( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* out_bool); + static void PPB_AudioConfig_RecommendSampleFrameCount( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + int32_t request_sample_rate, + int32_t request_sample_frame_count, + int32_t* out_sample_frame_count); + static void PPB_AudioConfig_GetSampleRate( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* sample_rate); + static void PPB_AudioConfig_GetSampleFrameCount( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* sample_frame_count); + + private: + PpbAudioConfigRpcServer(); + PpbAudioConfigRpcServer(const PpbAudioConfigRpcServer&); + void operator=(const PpbAudioConfigRpcServer); +}; // class PpbAudioConfigRpcServer + +class PpbCoreRpcServer { + public: + static void PPB_Core_AddRefResource( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource); + static void PPB_Core_ReleaseResource( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource); + static void ReleaseResourceMultipleTimes( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t count); + static void PPB_Core_GetTime( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + double* time); + static void PPB_Core_GetTimeTicks( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + double* time_ticks); + static void PPB_Core_CallOnMainThread( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + int32_t delay_in_milliseconds, + int32_t callback_id, + int32_t result); + + private: + PpbCoreRpcServer(); + PpbCoreRpcServer(const PpbCoreRpcServer&); + void operator=(const PpbCoreRpcServer); +}; // class PpbCoreRpcServer + +class PpbCursorControlRpcServer { + public: + static void PPB_CursorControl_SetCursor( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t type, + PP_Resource custom_image, + nacl_abi_size_t hot_spot_bytes, char* hot_spot, + int32_t* success); + static void PPB_CursorControl_LockCursor( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t* success); + static void PPB_CursorControl_UnlockCursor( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t* success); + static void PPB_CursorControl_HasCursorLock( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t* success); + static void PPB_CursorControl_CanLockCursor( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t* success); + + private: + PpbCursorControlRpcServer(); + PpbCursorControlRpcServer(const PpbCursorControlRpcServer&); + void operator=(const PpbCursorControlRpcServer); +}; // class PpbCursorControlRpcServer + +class PpbFileIORpcServer { + public: + static void PPB_FileIO_Create( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + PP_Resource* resource); + static void PPB_FileIO_IsFileIO( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* success); + static void PPB_FileIO_Open( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_io, + PP_Resource file_ref, + int32_t open_flags, + int32_t callback_id, + int32_t* pp_error); + static void PPB_FileIO_Query( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_io, + int32_t bytes_to_read, + int32_t callback_id, + nacl_abi_size_t* info_bytes, char* info, + int32_t* pp_error); + static void PPB_FileIO_Touch( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_io, + double last_access_time, + double last_modified_time, + int32_t callback_id, + int32_t* pp_error); + static void PPB_FileIO_Read( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_io, + int64_t offset, + int32_t bytes_to_read, + int32_t callback_id, + nacl_abi_size_t* buffer_bytes, char* buffer, + int32_t* pp_error_or_bytes); + static void PPB_FileIO_Write( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_io, + int64_t offset, + nacl_abi_size_t buffer_bytes, char* buffer, + int32_t bytes_to_write, + int32_t callback_id, + int32_t* pp_error_or_bytes); + static void PPB_FileIO_SetLength( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_io, + int64_t length, + int32_t callback_id, + int32_t* pp_error); + static void PPB_FileIO_Flush( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_io, + int32_t callback_id, + int32_t* pp_error); + static void PPB_FileIO_Close( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_io); + + private: + PpbFileIORpcServer(); + PpbFileIORpcServer(const PpbFileIORpcServer&); + void operator=(const PpbFileIORpcServer); +}; // class PpbFileIORpcServer + +class PpbFileRefRpcServer { + public: + static void PPB_FileRef_Create( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_system, + nacl_abi_size_t path_bytes, char* path, + PP_Resource* resource); + static void PPB_FileRef_IsFileRef( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* success); + static void PPB_FileRef_GetFileSystemType( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_ref, + int32_t* file_system_type); + static void PPB_FileRef_GetName( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_ref, + nacl_abi_size_t* name_bytes, char* name); + static void PPB_FileRef_GetPath( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_ref, + nacl_abi_size_t* path_bytes, char* path); + static void PPB_FileRef_GetParent( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_ref, + PP_Resource* parent); + static void PPB_FileRef_MakeDirectory( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource directory_ref, + int32_t make_ancestors, + int32_t callback_id, + int32_t* pp_error); + static void PPB_FileRef_Touch( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_ref, + double last_access_time, + double last_modified_time, + int32_t callback_id, + int32_t* pp_error); + static void PPB_FileRef_Delete( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_ref, + int32_t callback_id, + int32_t* pp_error); + static void PPB_FileRef_Rename( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_ref, + PP_Resource new_file_ref, + int32_t callback_id, + int32_t* pp_error); + + private: + PpbFileRefRpcServer(); + PpbFileRefRpcServer(const PpbFileRefRpcServer&); + void operator=(const PpbFileRefRpcServer); +}; // class PpbFileRefRpcServer + +class PpbFileSystemRpcServer { + public: + static void PPB_FileSystem_Create( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t file_system_type, + PP_Resource* resource); + static void PPB_FileSystem_IsFileSystem( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* success); + static void PPB_FileSystem_Open( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_system, + int64_t expected_size, + int32_t callback_id, + int32_t* pp_error); + static void PPB_FileSystem_GetType( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource file_system, + int32_t* type); + + private: + PpbFileSystemRpcServer(); + PpbFileSystemRpcServer(const PpbFileSystemRpcServer&); + void operator=(const PpbFileSystemRpcServer); +}; // class PpbFileSystemRpcServer + +class PpbFindRpcServer { + public: + static void PPB_Find_NumberOfFindResultsChanged( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t total, + int32_t final_result); + static void PPB_Find_SelectedFindResultChanged( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t index); + + private: + PpbFindRpcServer(); + PpbFindRpcServer(const PpbFindRpcServer&); + void operator=(const PpbFindRpcServer); +}; // class PpbFindRpcServer + +class PpbFontRpcServer { + public: + static void PPB_Font_GetFontFamilies( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + nacl_abi_size_t* font_families_bytes, char* font_families); + static void PPB_Font_Create( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + nacl_abi_size_t description_bytes, char* description, + nacl_abi_size_t face_bytes, char* face, + PP_Resource* font); + static void PPB_Font_IsFont( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* is_font); + static void PPB_Font_Describe( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource font, + nacl_abi_size_t* description_bytes, char* description, + nacl_abi_size_t* face_bytes, char* face, + nacl_abi_size_t* metrics_bytes, char* metrics, + int32_t* success); + static void PPB_Font_DrawTextAt( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource font, + PP_Resource image_data, + nacl_abi_size_t text_run_bytes, char* text_run, + nacl_abi_size_t text_bytes, char* text, + nacl_abi_size_t position_bytes, char* position, + int32_t color, + nacl_abi_size_t clip_bytes, char* clip, + int32_t image_data_is_opaque, + int32_t* success); + static void PPB_Font_MeasureText( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource font, + nacl_abi_size_t text_run_bytes, char* text_run, + nacl_abi_size_t text_bytes, char* text, + int32_t* width); + static void PPB_Font_CharacterOffsetForPixel( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource font, + nacl_abi_size_t text_run_bytes, char* text_run, + nacl_abi_size_t text_bytes, char* text, + int32_t pixel_position, + int32_t* offset); + static void PPB_Font_PixelOffsetForCharacter( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource font, + nacl_abi_size_t text_run_bytes, char* text_run, + nacl_abi_size_t text_bytes, char* text, + int32_t char_offset, + int32_t* offset); + + private: + PpbFontRpcServer(); + PpbFontRpcServer(const PpbFontRpcServer&); + void operator=(const PpbFontRpcServer); +}; // class PpbFontRpcServer + +class PpbGraphics2DRpcServer { + public: + static void PPB_Graphics2D_Create( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + nacl_abi_size_t size_bytes, char* size, + int32_t is_always_opaque, + PP_Resource* resource); + static void PPB_Graphics2D_IsGraphics2D( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* success); + static void PPB_Graphics2D_Describe( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource graphics_2d, + nacl_abi_size_t* size_bytes, char* size, + int32_t* is_always_opaque, + int32_t* success); + static void PPB_Graphics2D_PaintImageData( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource graphics_2d, + PP_Resource image, + nacl_abi_size_t top_left_bytes, char* top_left, + nacl_abi_size_t src_rect_bytes, char* src_rect); + static void PPB_Graphics2D_Scroll( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource graphics_2d, + nacl_abi_size_t clip_rect_bytes, char* clip_rect, + nacl_abi_size_t amount_bytes, char* amount); + static void PPB_Graphics2D_ReplaceContents( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource graphics_2d, + PP_Resource image); + static void PPB_Graphics2D_Flush( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource graphics_2d, + int32_t callback_id, + int32_t* pp_error); + + private: + PpbGraphics2DRpcServer(); + PpbGraphics2DRpcServer(const PpbGraphics2DRpcServer&); + void operator=(const PpbGraphics2DRpcServer); +}; // class PpbGraphics2DRpcServer + +class PpbGraphics3DRpcServer { + public: + static void PPB_Graphics3D_Create( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + PP_Resource share_context, + nacl_abi_size_t attrib_list_bytes, int32_t* attrib_list, + PP_Resource* resource_id); + static void PPB_Graphics3D_GetAttribs( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource context, + nacl_abi_size_t input_attrib_list_bytes, int32_t* input_attrib_list, + nacl_abi_size_t* output_attrib_list_bytes, int32_t* output_attrib_list, + int32_t* pp_error); + static void PPB_Graphics3D_SetAttribs( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource context, + nacl_abi_size_t attrib_list_bytes, int32_t* attrib_list, + int32_t* pp_error); + static void PPB_Graphics3D_ResizeBuffers( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource context, + int32_t width, + int32_t height, + int32_t* pp_error); + static void PPB_Graphics3D_SwapBuffers( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource context, + int32_t callback_id, + int32_t* pp_error); + static void PPB_Graphics3DTrusted_CreateRaw( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + PP_Resource share_context, + nacl_abi_size_t attrib_list_bytes, int32_t* attrib_list, + PP_Resource* resource_id); + static void PPB_Graphics3DTrusted_InitCommandBuffer( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource_id, + int32_t size, + int32_t* success); + static void PPB_Graphics3DTrusted_GetRingBuffer( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource_id, + NaClSrpcImcDescType* shm_desc, + int32_t* shm_size); + static void PPB_Graphics3DTrusted_GetState( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource_id, + nacl_abi_size_t* state_bytes, char* state); + static void PPB_Graphics3DTrusted_Flush( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource_id, + int32_t put_offset); + static void PPB_Graphics3DTrusted_FlushSync( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource_id, + int32_t put_offset, + nacl_abi_size_t* state_bytes, char* state); + static void PPB_Graphics3DTrusted_CreateTransferBuffer( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource_id, + int32_t size, + int32_t request_id, + int32_t* id); + static void PPB_Graphics3DTrusted_DestroyTransferBuffer( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource_id, + int32_t id); + static void PPB_Graphics3DTrusted_GetTransferBuffer( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource_id, + int32_t id, + NaClSrpcImcDescType* shm_desc, + int32_t* shm_size); + + private: + PpbGraphics3DRpcServer(); + PpbGraphics3DRpcServer(const PpbGraphics3DRpcServer&); + void operator=(const PpbGraphics3DRpcServer); +}; // class PpbGraphics3DRpcServer + +class PpbImageDataRpcServer { + public: + static void PPB_ImageData_GetNativeImageDataFormat( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + int32_t* format); + static void PPB_ImageData_IsImageDataFormatSupported( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + int32_t format, + int32_t* success); + static void PPB_ImageData_Create( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t format, + nacl_abi_size_t size_bytes, char* size, + int32_t init_to_zero, + PP_Resource* resource); + static void PPB_ImageData_IsImageData( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* success); + static void PPB_ImageData_Describe( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + nacl_abi_size_t* desc_bytes, char* desc, + NaClSrpcImcDescType* shm, + int32_t* shm_size, + int32_t* success); + + private: + PpbImageDataRpcServer(); + PpbImageDataRpcServer(const PpbImageDataRpcServer&); + void operator=(const PpbImageDataRpcServer); +}; // class PpbImageDataRpcServer + +class PpbInputEventRpcServer { + public: + static void PPB_InputEvent_RequestInputEvents( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t event_classes, + int32_t filtered, + int32_t* success); + static void PPB_InputEvent_ClearInputEventRequest( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t event_classes); + static void PPB_InputEvent_CreateMouseInputEvent( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t type, + double time_stamp, + int32_t modifiers, + int32_t mouse_button, + int32_t mouse_position_x, + int32_t mouse_position_y, + int32_t click_count, + PP_Resource* resource_id); + static void PPB_InputEvent_CreateWheelInputEvent( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + double time_stamp, + int32_t modifiers, + double wheel_delta_x, + double wheel_delta_y, + double wheel_ticks_x, + double wheel_ticks_y, + int32_t scroll_by_page, + PP_Resource* resource_id); + static void PPB_InputEvent_CreateKeyboardInputEvent( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t type, + double time_stamp, + int32_t modifiers, + int32_t key_code, + nacl_abi_size_t character_text_bytes, char* character_text, + PP_Resource* resource_id); + + private: + PpbInputEventRpcServer(); + PpbInputEventRpcServer(const PpbInputEventRpcServer&); + void operator=(const PpbInputEventRpcServer); +}; // class PpbInputEventRpcServer + +class PpbInstanceRpcServer { + public: + static void PPB_Instance_BindGraphics( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + PP_Resource graphics_device, + int32_t* success); + static void PPB_Instance_IsFullFrame( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t* is_full_frame); + + private: + PpbInstanceRpcServer(); + PpbInstanceRpcServer(const PpbInstanceRpcServer&); + void operator=(const PpbInstanceRpcServer); +}; // class PpbInstanceRpcServer + +class PpbMessagingRpcServer { + public: + static void PPB_Messaging_PostMessage( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + nacl_abi_size_t message_bytes, char* message); + + private: + PpbMessagingRpcServer(); + PpbMessagingRpcServer(const PpbMessagingRpcServer&); + void operator=(const PpbMessagingRpcServer); +}; // class PpbMessagingRpcServer + +class PpbPdfRpcServer { + public: + static void PPB_PDF_GetLocalizedString( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t string_id, + nacl_abi_size_t* string_bytes, char* string); + static void PPB_PDF_GetResourceImage( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t image_id, + PP_Resource* image); + static void PPB_PDF_GetFontFileWithFallback( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + nacl_abi_size_t description_bytes, char* description, + nacl_abi_size_t face_bytes, char* face, + int32_t charset, + PP_Resource* font); + static void PPB_PDF_GetFontTableForPrivateFontFile( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource font_file, + int32_t table, + nacl_abi_size_t* output_bytes, char* output, + int32_t* success); + static void PPB_PDF_SearchString( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + nacl_abi_size_t string_bytes, char* string, + nacl_abi_size_t term_bytes, char* term, + int32_t case_sensitive, + nacl_abi_size_t* results_bytes, char* results, + int32_t* count); + static void PPB_PDF_DidStartLoading( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance); + static void PPB_PDF_DidStopLoading( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance); + static void PPB_PDF_SetContentRestriction( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t restrictions); + static void PPB_PDF_HistogramPDFPageCount( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + int32_t count); + static void PPB_PDF_UserMetricsRecordAction( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + nacl_abi_size_t action_bytes, char* action); + static void PPB_PDF_HasUnsupportedFeature( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance); + static void PPB_PDF_SaveAs( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance); + + private: + PpbPdfRpcServer(); + PpbPdfRpcServer(const PpbPdfRpcServer&); + void operator=(const PpbPdfRpcServer); +}; // class PpbPdfRpcServer + +class PpbScrollbarRpcServer { + public: + static void PPB_Scrollbar_Create( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t vertical, + PP_Resource* scrollbar); + static void PPB_Scrollbar_IsScrollbar( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* is_scrollbar); + static void PPB_Scrollbar_IsOverlay( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* is_overlay); + static void PPB_Scrollbar_GetThickness( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* thickness); + static void PPB_Scrollbar_GetValue( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource scrollbar, + int32_t* value); + static void PPB_Scrollbar_SetValue( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource scrollbar, + int32_t value); + static void PPB_Scrollbar_SetDocumentSize( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource scrollbar, + int32_t size); + static void PPB_Scrollbar_SetTickMarks( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource scrollbar, + nacl_abi_size_t tick_marks_bytes, char* tick_marks, + int32_t count); + static void PPB_Scrollbar_ScrollBy( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource scrollbar, + int32_t unit, + int32_t multiplier); + + private: + PpbScrollbarRpcServer(); + PpbScrollbarRpcServer(const PpbScrollbarRpcServer&); + void operator=(const PpbScrollbarRpcServer); +}; // class PpbScrollbarRpcServer + +class PpbTestingRpcServer { + public: + static void PPB_Testing_ReadImageData( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource device_context_2d, + PP_Resource image, + nacl_abi_size_t top_left_bytes, char* top_left, + int32_t* success); + static void PPB_Testing_RunMessageLoop( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance); + static void PPB_Testing_QuitMessageLoop( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance); + static void PPB_Testing_GetLiveObjectsForInstance( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t* live_object_count); + + private: + PpbTestingRpcServer(); + PpbTestingRpcServer(const PpbTestingRpcServer&); + void operator=(const PpbTestingRpcServer); +}; // class PpbTestingRpcServer + +class PpbURLLoaderRpcServer { + public: + static void PPB_URLLoader_Create( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + PP_Resource* resource); + static void PPB_URLLoader_IsURLLoader( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* is_url_loader); + static void PPB_URLLoader_Open( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource loader, + PP_Resource request, + int32_t callback_id, + int32_t* pp_error); + static void PPB_URLLoader_FollowRedirect( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource loader, + int32_t callback_id, + int32_t* pp_error); + static void PPB_URLLoader_GetUploadProgress( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource loader, + int64_t* bytes_sent, + int64_t* total_bytes_to_be_sent, + int32_t* success); + static void PPB_URLLoader_GetDownloadProgress( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource loader, + int64_t* bytes_received, + int64_t* total_bytes_to_be_received, + int32_t* success); + static void PPB_URLLoader_GetResponseInfo( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource loader, + PP_Resource* response); + static void PPB_URLLoader_ReadResponseBody( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource loader, + int32_t bytes_to_read, + int32_t callback_id, + nacl_abi_size_t* buffer_bytes, char* buffer, + int32_t* pp_error_or_bytes); + static void PPB_URLLoader_FinishStreamingToFile( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource loader, + int32_t callback_id, + int32_t* pp_error); + static void PPB_URLLoader_Close( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource loader); + + private: + PpbURLLoaderRpcServer(); + PpbURLLoaderRpcServer(const PpbURLLoaderRpcServer&); + void operator=(const PpbURLLoaderRpcServer); +}; // class PpbURLLoaderRpcServer + +class PpbURLRequestInfoRpcServer { + public: + static void PPB_URLRequestInfo_Create( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + PP_Resource* resource); + static void PPB_URLRequestInfo_IsURLRequestInfo( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* success); + static void PPB_URLRequestInfo_SetProperty( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource request, + int32_t property, + nacl_abi_size_t value_bytes, char* value, + int32_t* success); + static void PPB_URLRequestInfo_AppendDataToBody( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource request, + nacl_abi_size_t data_bytes, char* data, + int32_t* success); + static void PPB_URLRequestInfo_AppendFileToBody( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource request, + PP_Resource file_ref, + int64_t start_offset, + int64_t number_of_bytes, + double expected_last_modified_time, + int32_t* success); + + private: + PpbURLRequestInfoRpcServer(); + PpbURLRequestInfoRpcServer(const PpbURLRequestInfoRpcServer&); + void operator=(const PpbURLRequestInfoRpcServer); +}; // class PpbURLRequestInfoRpcServer + +class PpbURLResponseInfoRpcServer { + public: + static void PPB_URLResponseInfo_IsURLResponseInfo( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* success); + static void PPB_URLResponseInfo_GetProperty( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource response, + int32_t property, + nacl_abi_size_t* value_bytes, char* value); + static void PPB_URLResponseInfo_GetBodyAsFileRef( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource response, + PP_Resource* file_ref); + + private: + PpbURLResponseInfoRpcServer(); + PpbURLResponseInfoRpcServer(const PpbURLResponseInfoRpcServer&); + void operator=(const PpbURLResponseInfoRpcServer); +}; // class PpbURLResponseInfoRpcServer + +class PpbWidgetRpcServer { + public: + static void PPB_Widget_IsWidget( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource resource, + int32_t* is_widget); + static void PPB_Widget_Paint( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource widget, + nacl_abi_size_t rect_bytes, char* rect, + PP_Resource image, + int32_t* success); + static void PPB_Widget_HandleEvent( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource widget, + PP_Resource event, + int32_t* handled); + static void PPB_Widget_GetLocation( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource widget, + nacl_abi_size_t* location_bytes, char* location, + int32_t* visible); + static void PPB_Widget_SetLocation( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Resource widget, + nacl_abi_size_t location_bytes, char* location); + + private: + PpbWidgetRpcServer(); + PpbWidgetRpcServer(const PpbWidgetRpcServer&); + void operator=(const PpbWidgetRpcServer); +}; // class PpbWidgetRpcServer + +class PpbZoomRpcServer { + public: + static void PPB_Zoom_ZoomChanged( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + double factor); + static void PPB_Zoom_ZoomLimitsChanged( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + double minimum_factor, + double maximum_factor); + + private: + PpbZoomRpcServer(); + PpbZoomRpcServer(const PpbZoomRpcServer&); + void operator=(const PpbZoomRpcServer); +}; // class PpbZoomRpcServer + +class PpbRpcs { + public: + static NaClSrpcHandlerDesc srpc_methods[]; +}; // class PpbRpcs + + +#endif // GEN_PPAPI_PROXY_PPB_RPC_H_ + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/trusted/srpcgen/ppp_rpc.h b/ppapi/native_client/src/shared/ppapi_proxy/trusted/srpcgen/ppp_rpc.h new file mode 100644 index 0000000..a1c70c6 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/trusted/srpcgen/ppp_rpc.h @@ -0,0 +1,251 @@ +// 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. +// +// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING +// +// Automatically generated code. See srpcgen.py +// +// NaCl Simple Remote Procedure Call interface abstractions. + +#ifndef GEN_PPAPI_PROXY_PPP_RPC_H_ +#define GEN_PPAPI_PROXY_PPP_RPC_H_ + +#ifndef __native_client__ +#include "native_client/src/include/portability.h" +#endif // __native_client__ +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_resource.h" + +class CompletionCallbackRpcClient { + public: + static NaClSrpcError RunCompletionCallback( + NaClSrpcChannel* channel, + int32_t callback_id, + int32_t result, + nacl_abi_size_t read_buffer_bytes, char* read_buffer); + + private: + CompletionCallbackRpcClient(); + CompletionCallbackRpcClient(const CompletionCallbackRpcClient&); + void operator=(const CompletionCallbackRpcClient); +}; // class CompletionCallbackRpcClient + +class PppRpcClient { + public: + static NaClSrpcError PPP_InitializeModule( + NaClSrpcChannel* channel, + int32_t pid, + PP_Module module, + NaClSrpcImcDescType upcall_channel_desc, + char* service_description, + int32_t* nacl_pid, + int32_t* success); + static NaClSrpcError PPP_ShutdownModule( + NaClSrpcChannel* channel); + static NaClSrpcError PPP_GetInterface( + NaClSrpcChannel* channel, + char* interface_name, + int32_t* exports_interface_name); + + private: + PppRpcClient(); + PppRpcClient(const PppRpcClient&); + void operator=(const PppRpcClient); +}; // class PppRpcClient + +class PppAudioRpcClient { + public: + static NaClSrpcError PPP_Audio_StreamCreated( + NaClSrpcChannel* channel, + PP_Instance instance, + NaClSrpcImcDescType out_shm, + int32_t out_shm_size, + NaClSrpcImcDescType out_socket); + + private: + PppAudioRpcClient(); + PppAudioRpcClient(const PppAudioRpcClient&); + void operator=(const PppAudioRpcClient); +}; // class PppAudioRpcClient + +class PppFindRpcClient { + public: + static NaClSrpcError PPP_Find_StartFind( + NaClSrpcChannel* channel, + PP_Instance instance, + nacl_abi_size_t text_bytes, char* text, + int32_t case_sensitive, + int32_t* supports_find); + static NaClSrpcError PPP_Find_SelectFindResult( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t forward); + static NaClSrpcError PPP_Find_StopFind( + NaClSrpcChannel* channel, + PP_Instance instance); + + private: + PppFindRpcClient(); + PppFindRpcClient(const PppFindRpcClient&); + void operator=(const PppFindRpcClient); +}; // class PppFindRpcClient + +class PppInputEventRpcClient { + public: + static NaClSrpcError PPP_InputEvent_HandleInputEvent( + NaClSrpcChannel* channel, + PP_Instance instance, + PP_Resource resource, + nacl_abi_size_t event_data_bytes, char* event_data, + nacl_abi_size_t character_text_bytes, char* character_text, + int32_t* handled); + + private: + PppInputEventRpcClient(); + PppInputEventRpcClient(const PppInputEventRpcClient&); + void operator=(const PppInputEventRpcClient); +}; // class PppInputEventRpcClient + +class PppInstanceRpcClient { + public: + static NaClSrpcError PPP_Instance_DidCreate( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t argc, + nacl_abi_size_t argn_bytes, char* argn, + nacl_abi_size_t argv_bytes, char* argv, + int32_t* success); + static NaClSrpcError PPP_Instance_DidDestroy( + NaClSrpcChannel* channel, + PP_Instance instance); + static NaClSrpcError PPP_Instance_DidChangeView( + NaClSrpcChannel* channel, + PP_Instance instance, + nacl_abi_size_t position_bytes, int32_t* position, + nacl_abi_size_t clip_bytes, int32_t* clip); + static NaClSrpcError PPP_Instance_DidChangeFocus( + NaClSrpcChannel* channel, + PP_Instance instance, + bool has_focus); + static NaClSrpcError PPP_Instance_HandleDocumentLoad( + NaClSrpcChannel* channel, + PP_Instance instance, + PP_Resource url_loader, + int32_t* success); + + private: + PppInstanceRpcClient(); + PppInstanceRpcClient(const PppInstanceRpcClient&); + void operator=(const PppInstanceRpcClient); +}; // class PppInstanceRpcClient + +class PppMessagingRpcClient { + public: + static NaClSrpcError PPP_Messaging_HandleMessage( + NaClSrpcChannel* channel, + PP_Instance instance, + nacl_abi_size_t message_bytes, char* message); + + private: + PppMessagingRpcClient(); + PppMessagingRpcClient(const PppMessagingRpcClient&); + void operator=(const PppMessagingRpcClient); +}; // class PppMessagingRpcClient + +class PppPrintingRpcClient { + public: + static NaClSrpcError PPP_Printing_QuerySupportedFormats( + NaClSrpcChannel* channel, + PP_Instance instance, + nacl_abi_size_t* formats_bytes, char* formats, + int32_t* format_count); + static NaClSrpcError PPP_Printing_Begin( + NaClSrpcChannel* channel, + PP_Instance instance, + nacl_abi_size_t print_settings_bytes, char* print_settings, + int32_t* pages_required); + static NaClSrpcError PPP_Printing_PrintPages( + NaClSrpcChannel* channel, + PP_Instance instance, + nacl_abi_size_t page_ranges_bytes, char* page_ranges, + int32_t page_range_count, + PP_Resource* image_data); + static NaClSrpcError PPP_Printing_End( + NaClSrpcChannel* channel, + PP_Instance instance); + + private: + PppPrintingRpcClient(); + PppPrintingRpcClient(const PppPrintingRpcClient&); + void operator=(const PppPrintingRpcClient); +}; // class PppPrintingRpcClient + +class PppScrollbarRpcClient { + public: + static NaClSrpcError PPP_Scrollbar_ValueChanged( + NaClSrpcChannel* channel, + PP_Instance instance, + PP_Resource scrollbar, + int32_t value); + static NaClSrpcError PPP_Scrollbar_OverlayChanged( + NaClSrpcChannel* channel, + PP_Instance instance, + PP_Resource scrollbar, + int32_t overlay); + + private: + PppScrollbarRpcClient(); + PppScrollbarRpcClient(const PppScrollbarRpcClient&); + void operator=(const PppScrollbarRpcClient); +}; // class PppScrollbarRpcClient + +class PppSelectionRpcClient { + public: + static NaClSrpcError PPP_Selection_GetSelectedText( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t html, + nacl_abi_size_t* selected_text_bytes, char* selected_text); + + private: + PppSelectionRpcClient(); + PppSelectionRpcClient(const PppSelectionRpcClient&); + void operator=(const PppSelectionRpcClient); +}; // class PppSelectionRpcClient + +class PppWidgetRpcClient { + public: + static NaClSrpcError PPP_Widget_Invalidate( + NaClSrpcChannel* channel, + PP_Instance instance, + PP_Resource widget, + nacl_abi_size_t dirty_rect_bytes, char* dirty_rect); + + private: + PppWidgetRpcClient(); + PppWidgetRpcClient(const PppWidgetRpcClient&); + void operator=(const PppWidgetRpcClient); +}; // class PppWidgetRpcClient + +class PppZoomRpcClient { + public: + static NaClSrpcError PPP_Zoom_Zoom( + NaClSrpcChannel* channel, + PP_Instance instance, + double factor, + int32_t text_only); + + private: + PppZoomRpcClient(); + PppZoomRpcClient(const PppZoomRpcClient&); + void operator=(const PppZoomRpcClient); +}; // class PppZoomRpcClient + + + + +#endif // GEN_PPAPI_PROXY_PPP_RPC_H_ + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/trusted/srpcgen/upcall.h b/ppapi/native_client/src/shared/ppapi_proxy/trusted/srpcgen/upcall.h new file mode 100644 index 0000000..617e709 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/trusted/srpcgen/upcall.h @@ -0,0 +1,44 @@ +// 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. +// +// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING +// +// Automatically generated code. See srpcgen.py +// +// NaCl Simple Remote Procedure Call interface abstractions. + +#ifndef GEN_PPAPI_PROXY_UPCALL_H_ +#define GEN_PPAPI_PROXY_UPCALL_H_ + +#ifndef __native_client__ +#include "native_client/src/include/portability.h" +#endif // __native_client__ +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_resource.h" + +class PppUpcallRpcServer { + public: + static void PPB_Core_CallOnMainThread( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + int32_t delay_in_milliseconds, + int32_t callback_id, + int32_t result); + + private: + PppUpcallRpcServer(); + PppUpcallRpcServer(const PppUpcallRpcServer&); + void operator=(const PppUpcallRpcServer); +}; // class PppUpcallRpcServer + +class PpbUpcalls { + public: + static NaClSrpcHandlerDesc srpc_methods[]; +}; // class PpbUpcalls + + +#endif // GEN_PPAPI_PROXY_UPCALL_H_ + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/untrusted/srpcgen/ppb_rpc.h b/ppapi/native_client/src/shared/ppapi_proxy/untrusted/srpcgen/ppb_rpc.h new file mode 100644 index 0000000..de11eb6 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/untrusted/srpcgen/ppb_rpc.h @@ -0,0 +1,960 @@ +// 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. +// +// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING +// +// Automatically generated code. See srpcgen.py +// +// NaCl Simple Remote Procedure Call interface abstractions. + +#ifndef GEN_PPAPI_PROXY_PPB_RPC_H_ +#define GEN_PPAPI_PROXY_PPB_RPC_H_ + +#ifndef __native_client__ +#include "native_client/src/include/portability.h" +#endif // __native_client__ +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_resource.h" + +class NaClFileRpcClient { + public: + static NaClSrpcError StreamAsFile( + NaClSrpcChannel* channel, + PP_Instance instance, + char* url, + int32_t callback_id); + static NaClSrpcError GetFileDesc( + NaClSrpcChannel* channel, + PP_Instance instance, + char* url, + NaClSrpcImcDescType* file_desc); + + private: + NaClFileRpcClient(); + NaClFileRpcClient(const NaClFileRpcClient&); + void operator=(const NaClFileRpcClient); +}; // class NaClFileRpcClient + +class PpbRpcClient { + public: + static NaClSrpcError PPB_GetInterface( + NaClSrpcChannel* channel, + char* interface_name, + int32_t* exports_interface_name); + + private: + PpbRpcClient(); + PpbRpcClient(const PpbRpcClient&); + void operator=(const PpbRpcClient); +}; // class PpbRpcClient + +class PpbAudioRpcClient { + public: + static NaClSrpcError PPB_Audio_Create( + NaClSrpcChannel* channel, + PP_Instance instance, + PP_Resource config, + PP_Resource* out_resource); + static NaClSrpcError PPB_Audio_IsAudio( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* out_bool); + static NaClSrpcError PPB_Audio_GetCurrentConfig( + NaClSrpcChannel* channel, + PP_Resource resource, + PP_Resource* out_resource); + static NaClSrpcError PPB_Audio_StopPlayback( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* out_bool); + static NaClSrpcError PPB_Audio_StartPlayback( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* out_bool); + + private: + PpbAudioRpcClient(); + PpbAudioRpcClient(const PpbAudioRpcClient&); + void operator=(const PpbAudioRpcClient); +}; // class PpbAudioRpcClient + +class PpbAudioConfigRpcClient { + public: + static NaClSrpcError PPB_AudioConfig_CreateStereo16Bit( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t sample_rate, + int32_t sample_frame_count, + PP_Resource* resource); + static NaClSrpcError PPB_AudioConfig_IsAudioConfig( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* out_bool); + static NaClSrpcError PPB_AudioConfig_RecommendSampleFrameCount( + NaClSrpcChannel* channel, + int32_t request_sample_rate, + int32_t request_sample_frame_count, + int32_t* out_sample_frame_count); + static NaClSrpcError PPB_AudioConfig_GetSampleRate( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* sample_rate); + static NaClSrpcError PPB_AudioConfig_GetSampleFrameCount( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* sample_frame_count); + + private: + PpbAudioConfigRpcClient(); + PpbAudioConfigRpcClient(const PpbAudioConfigRpcClient&); + void operator=(const PpbAudioConfigRpcClient); +}; // class PpbAudioConfigRpcClient + +class PpbCoreRpcClient { + public: + static NaClSrpcError PPB_Core_AddRefResource( + NaClSrpcChannel* channel, + PP_Resource resource); + static NaClSrpcError PPB_Core_ReleaseResource( + NaClSrpcChannel* channel, + PP_Resource resource); + static NaClSrpcError ReleaseResourceMultipleTimes( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t count); + static NaClSrpcError PPB_Core_GetTime( + NaClSrpcChannel* channel, + double* time); + static NaClSrpcError PPB_Core_GetTimeTicks( + NaClSrpcChannel* channel, + double* time_ticks); + static NaClSrpcError PPB_Core_CallOnMainThread( + NaClSrpcChannel* channel, + int32_t delay_in_milliseconds, + int32_t callback_id, + int32_t result); + + private: + PpbCoreRpcClient(); + PpbCoreRpcClient(const PpbCoreRpcClient&); + void operator=(const PpbCoreRpcClient); +}; // class PpbCoreRpcClient + +class PpbCursorControlRpcClient { + public: + static NaClSrpcError PPB_CursorControl_SetCursor( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t type, + PP_Resource custom_image, + nacl_abi_size_t hot_spot_bytes, char* hot_spot, + int32_t* success); + static NaClSrpcError PPB_CursorControl_LockCursor( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t* success); + static NaClSrpcError PPB_CursorControl_UnlockCursor( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t* success); + static NaClSrpcError PPB_CursorControl_HasCursorLock( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t* success); + static NaClSrpcError PPB_CursorControl_CanLockCursor( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t* success); + + private: + PpbCursorControlRpcClient(); + PpbCursorControlRpcClient(const PpbCursorControlRpcClient&); + void operator=(const PpbCursorControlRpcClient); +}; // class PpbCursorControlRpcClient + +class PpbFileIORpcClient { + public: + static NaClSrpcError PPB_FileIO_Create( + NaClSrpcChannel* channel, + PP_Instance instance, + PP_Resource* resource); + static NaClSrpcError PPB_FileIO_IsFileIO( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* success); + static NaClSrpcError PPB_FileIO_Open( + NaClSrpcChannel* channel, + PP_Resource file_io, + PP_Resource file_ref, + int32_t open_flags, + int32_t callback_id, + int32_t* pp_error); + static NaClSrpcError PPB_FileIO_Query( + NaClSrpcChannel* channel, + PP_Resource file_io, + int32_t bytes_to_read, + int32_t callback_id, + nacl_abi_size_t* info_bytes, char* info, + int32_t* pp_error); + static NaClSrpcError PPB_FileIO_Touch( + NaClSrpcChannel* channel, + PP_Resource file_io, + double last_access_time, + double last_modified_time, + int32_t callback_id, + int32_t* pp_error); + static NaClSrpcError PPB_FileIO_Read( + NaClSrpcChannel* channel, + PP_Resource file_io, + int64_t offset, + int32_t bytes_to_read, + int32_t callback_id, + nacl_abi_size_t* buffer_bytes, char* buffer, + int32_t* pp_error_or_bytes); + static NaClSrpcError PPB_FileIO_Write( + NaClSrpcChannel* channel, + PP_Resource file_io, + int64_t offset, + nacl_abi_size_t buffer_bytes, char* buffer, + int32_t bytes_to_write, + int32_t callback_id, + int32_t* pp_error_or_bytes); + static NaClSrpcError PPB_FileIO_SetLength( + NaClSrpcChannel* channel, + PP_Resource file_io, + int64_t length, + int32_t callback_id, + int32_t* pp_error); + static NaClSrpcError PPB_FileIO_Flush( + NaClSrpcChannel* channel, + PP_Resource file_io, + int32_t callback_id, + int32_t* pp_error); + static NaClSrpcError PPB_FileIO_Close( + NaClSrpcChannel* channel, + PP_Resource file_io); + + private: + PpbFileIORpcClient(); + PpbFileIORpcClient(const PpbFileIORpcClient&); + void operator=(const PpbFileIORpcClient); +}; // class PpbFileIORpcClient + +class PpbFileRefRpcClient { + public: + static NaClSrpcError PPB_FileRef_Create( + NaClSrpcChannel* channel, + PP_Resource file_system, + nacl_abi_size_t path_bytes, char* path, + PP_Resource* resource); + static NaClSrpcError PPB_FileRef_IsFileRef( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* success); + static NaClSrpcError PPB_FileRef_GetFileSystemType( + NaClSrpcChannel* channel, + PP_Resource file_ref, + int32_t* file_system_type); + static NaClSrpcError PPB_FileRef_GetName( + NaClSrpcChannel* channel, + PP_Resource file_ref, + nacl_abi_size_t* name_bytes, char* name); + static NaClSrpcError PPB_FileRef_GetPath( + NaClSrpcChannel* channel, + PP_Resource file_ref, + nacl_abi_size_t* path_bytes, char* path); + static NaClSrpcError PPB_FileRef_GetParent( + NaClSrpcChannel* channel, + PP_Resource file_ref, + PP_Resource* parent); + static NaClSrpcError PPB_FileRef_MakeDirectory( + NaClSrpcChannel* channel, + PP_Resource directory_ref, + int32_t make_ancestors, + int32_t callback_id, + int32_t* pp_error); + static NaClSrpcError PPB_FileRef_Touch( + NaClSrpcChannel* channel, + PP_Resource file_ref, + double last_access_time, + double last_modified_time, + int32_t callback_id, + int32_t* pp_error); + static NaClSrpcError PPB_FileRef_Delete( + NaClSrpcChannel* channel, + PP_Resource file_ref, + int32_t callback_id, + int32_t* pp_error); + static NaClSrpcError PPB_FileRef_Rename( + NaClSrpcChannel* channel, + PP_Resource file_ref, + PP_Resource new_file_ref, + int32_t callback_id, + int32_t* pp_error); + + private: + PpbFileRefRpcClient(); + PpbFileRefRpcClient(const PpbFileRefRpcClient&); + void operator=(const PpbFileRefRpcClient); +}; // class PpbFileRefRpcClient + +class PpbFileSystemRpcClient { + public: + static NaClSrpcError PPB_FileSystem_Create( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t file_system_type, + PP_Resource* resource); + static NaClSrpcError PPB_FileSystem_IsFileSystem( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* success); + static NaClSrpcError PPB_FileSystem_Open( + NaClSrpcChannel* channel, + PP_Resource file_system, + int64_t expected_size, + int32_t callback_id, + int32_t* pp_error); + static NaClSrpcError PPB_FileSystem_GetType( + NaClSrpcChannel* channel, + PP_Resource file_system, + int32_t* type); + + private: + PpbFileSystemRpcClient(); + PpbFileSystemRpcClient(const PpbFileSystemRpcClient&); + void operator=(const PpbFileSystemRpcClient); +}; // class PpbFileSystemRpcClient + +class PpbFindRpcClient { + public: + static NaClSrpcError PPB_Find_NumberOfFindResultsChanged( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t total, + int32_t final_result); + static NaClSrpcError PPB_Find_SelectedFindResultChanged( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t index); + + private: + PpbFindRpcClient(); + PpbFindRpcClient(const PpbFindRpcClient&); + void operator=(const PpbFindRpcClient); +}; // class PpbFindRpcClient + +class PpbFontRpcClient { + public: + static NaClSrpcError PPB_Font_GetFontFamilies( + NaClSrpcChannel* channel, + PP_Instance instance, + nacl_abi_size_t* font_families_bytes, char* font_families); + static NaClSrpcError PPB_Font_Create( + NaClSrpcChannel* channel, + PP_Instance instance, + nacl_abi_size_t description_bytes, char* description, + nacl_abi_size_t face_bytes, char* face, + PP_Resource* font); + static NaClSrpcError PPB_Font_IsFont( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* is_font); + static NaClSrpcError PPB_Font_Describe( + NaClSrpcChannel* channel, + PP_Resource font, + nacl_abi_size_t* description_bytes, char* description, + nacl_abi_size_t* face_bytes, char* face, + nacl_abi_size_t* metrics_bytes, char* metrics, + int32_t* success); + static NaClSrpcError PPB_Font_DrawTextAt( + NaClSrpcChannel* channel, + PP_Resource font, + PP_Resource image_data, + nacl_abi_size_t text_run_bytes, char* text_run, + nacl_abi_size_t text_bytes, char* text, + nacl_abi_size_t position_bytes, char* position, + int32_t color, + nacl_abi_size_t clip_bytes, char* clip, + int32_t image_data_is_opaque, + int32_t* success); + static NaClSrpcError PPB_Font_MeasureText( + NaClSrpcChannel* channel, + PP_Resource font, + nacl_abi_size_t text_run_bytes, char* text_run, + nacl_abi_size_t text_bytes, char* text, + int32_t* width); + static NaClSrpcError PPB_Font_CharacterOffsetForPixel( + NaClSrpcChannel* channel, + PP_Resource font, + nacl_abi_size_t text_run_bytes, char* text_run, + nacl_abi_size_t text_bytes, char* text, + int32_t pixel_position, + int32_t* offset); + static NaClSrpcError PPB_Font_PixelOffsetForCharacter( + NaClSrpcChannel* channel, + PP_Resource font, + nacl_abi_size_t text_run_bytes, char* text_run, + nacl_abi_size_t text_bytes, char* text, + int32_t char_offset, + int32_t* offset); + + private: + PpbFontRpcClient(); + PpbFontRpcClient(const PpbFontRpcClient&); + void operator=(const PpbFontRpcClient); +}; // class PpbFontRpcClient + +class PpbGraphics2DRpcClient { + public: + static NaClSrpcError PPB_Graphics2D_Create( + NaClSrpcChannel* channel, + PP_Instance instance, + nacl_abi_size_t size_bytes, char* size, + int32_t is_always_opaque, + PP_Resource* resource); + static NaClSrpcError PPB_Graphics2D_IsGraphics2D( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* success); + static NaClSrpcError PPB_Graphics2D_Describe( + NaClSrpcChannel* channel, + PP_Resource graphics_2d, + nacl_abi_size_t* size_bytes, char* size, + int32_t* is_always_opaque, + int32_t* success); + static NaClSrpcError PPB_Graphics2D_PaintImageData( + NaClSrpcChannel* channel, + PP_Resource graphics_2d, + PP_Resource image, + nacl_abi_size_t top_left_bytes, char* top_left, + nacl_abi_size_t src_rect_bytes, char* src_rect); + static NaClSrpcError PPB_Graphics2D_Scroll( + NaClSrpcChannel* channel, + PP_Resource graphics_2d, + nacl_abi_size_t clip_rect_bytes, char* clip_rect, + nacl_abi_size_t amount_bytes, char* amount); + static NaClSrpcError PPB_Graphics2D_ReplaceContents( + NaClSrpcChannel* channel, + PP_Resource graphics_2d, + PP_Resource image); + static NaClSrpcError PPB_Graphics2D_Flush( + NaClSrpcChannel* channel, + PP_Resource graphics_2d, + int32_t callback_id, + int32_t* pp_error); + + private: + PpbGraphics2DRpcClient(); + PpbGraphics2DRpcClient(const PpbGraphics2DRpcClient&); + void operator=(const PpbGraphics2DRpcClient); +}; // class PpbGraphics2DRpcClient + +class PpbGraphics3DRpcClient { + public: + static NaClSrpcError PPB_Graphics3D_Create( + NaClSrpcChannel* channel, + PP_Instance instance, + PP_Resource share_context, + nacl_abi_size_t attrib_list_bytes, int32_t* attrib_list, + PP_Resource* resource_id); + static NaClSrpcError PPB_Graphics3D_GetAttribs( + NaClSrpcChannel* channel, + PP_Resource context, + nacl_abi_size_t input_attrib_list_bytes, int32_t* input_attrib_list, + nacl_abi_size_t* output_attrib_list_bytes, int32_t* output_attrib_list, + int32_t* pp_error); + static NaClSrpcError PPB_Graphics3D_SetAttribs( + NaClSrpcChannel* channel, + PP_Resource context, + nacl_abi_size_t attrib_list_bytes, int32_t* attrib_list, + int32_t* pp_error); + static NaClSrpcError PPB_Graphics3D_ResizeBuffers( + NaClSrpcChannel* channel, + PP_Resource context, + int32_t width, + int32_t height, + int32_t* pp_error); + static NaClSrpcError PPB_Graphics3D_SwapBuffers( + NaClSrpcChannel* channel, + PP_Resource context, + int32_t callback_id, + int32_t* pp_error); + static NaClSrpcError PPB_Graphics3DTrusted_CreateRaw( + NaClSrpcChannel* channel, + PP_Instance instance, + PP_Resource share_context, + nacl_abi_size_t attrib_list_bytes, int32_t* attrib_list, + PP_Resource* resource_id); + static NaClSrpcError PPB_Graphics3DTrusted_InitCommandBuffer( + NaClSrpcChannel* channel, + PP_Resource resource_id, + int32_t size, + int32_t* success); + static NaClSrpcError PPB_Graphics3DTrusted_GetRingBuffer( + NaClSrpcChannel* channel, + PP_Resource resource_id, + NaClSrpcImcDescType* shm_desc, + int32_t* shm_size); + static NaClSrpcError PPB_Graphics3DTrusted_GetState( + NaClSrpcChannel* channel, + PP_Resource resource_id, + nacl_abi_size_t* state_bytes, char* state); + static NaClSrpcError PPB_Graphics3DTrusted_Flush( + NaClSrpcChannel* channel, + PP_Resource resource_id, + int32_t put_offset); + static NaClSrpcError PPB_Graphics3DTrusted_FlushSync( + NaClSrpcChannel* channel, + PP_Resource resource_id, + int32_t put_offset, + nacl_abi_size_t* state_bytes, char* state); + static NaClSrpcError PPB_Graphics3DTrusted_CreateTransferBuffer( + NaClSrpcChannel* channel, + PP_Resource resource_id, + int32_t size, + int32_t request_id, + int32_t* id); + static NaClSrpcError PPB_Graphics3DTrusted_DestroyTransferBuffer( + NaClSrpcChannel* channel, + PP_Resource resource_id, + int32_t id); + static NaClSrpcError PPB_Graphics3DTrusted_GetTransferBuffer( + NaClSrpcChannel* channel, + PP_Resource resource_id, + int32_t id, + NaClSrpcImcDescType* shm_desc, + int32_t* shm_size); + + private: + PpbGraphics3DRpcClient(); + PpbGraphics3DRpcClient(const PpbGraphics3DRpcClient&); + void operator=(const PpbGraphics3DRpcClient); +}; // class PpbGraphics3DRpcClient + +class PpbImageDataRpcClient { + public: + static NaClSrpcError PPB_ImageData_GetNativeImageDataFormat( + NaClSrpcChannel* channel, + int32_t* format); + static NaClSrpcError PPB_ImageData_IsImageDataFormatSupported( + NaClSrpcChannel* channel, + int32_t format, + int32_t* success); + static NaClSrpcError PPB_ImageData_Create( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t format, + nacl_abi_size_t size_bytes, char* size, + int32_t init_to_zero, + PP_Resource* resource); + static NaClSrpcError PPB_ImageData_IsImageData( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* success); + static NaClSrpcError PPB_ImageData_Describe( + NaClSrpcChannel* channel, + PP_Resource resource, + nacl_abi_size_t* desc_bytes, char* desc, + NaClSrpcImcDescType* shm, + int32_t* shm_size, + int32_t* success); + + private: + PpbImageDataRpcClient(); + PpbImageDataRpcClient(const PpbImageDataRpcClient&); + void operator=(const PpbImageDataRpcClient); +}; // class PpbImageDataRpcClient + +class PpbInputEventRpcClient { + public: + static NaClSrpcError PPB_InputEvent_RequestInputEvents( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t event_classes, + int32_t filtered, + int32_t* success); + static NaClSrpcError PPB_InputEvent_ClearInputEventRequest( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t event_classes); + static NaClSrpcError PPB_InputEvent_CreateMouseInputEvent( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t type, + double time_stamp, + int32_t modifiers, + int32_t mouse_button, + int32_t mouse_position_x, + int32_t mouse_position_y, + int32_t click_count, + PP_Resource* resource_id); + static NaClSrpcError PPB_InputEvent_CreateWheelInputEvent( + NaClSrpcChannel* channel, + PP_Instance instance, + double time_stamp, + int32_t modifiers, + double wheel_delta_x, + double wheel_delta_y, + double wheel_ticks_x, + double wheel_ticks_y, + int32_t scroll_by_page, + PP_Resource* resource_id); + static NaClSrpcError PPB_InputEvent_CreateKeyboardInputEvent( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t type, + double time_stamp, + int32_t modifiers, + int32_t key_code, + nacl_abi_size_t character_text_bytes, char* character_text, + PP_Resource* resource_id); + + private: + PpbInputEventRpcClient(); + PpbInputEventRpcClient(const PpbInputEventRpcClient&); + void operator=(const PpbInputEventRpcClient); +}; // class PpbInputEventRpcClient + +class PpbInstanceRpcClient { + public: + static NaClSrpcError PPB_Instance_BindGraphics( + NaClSrpcChannel* channel, + PP_Instance instance, + PP_Resource graphics_device, + int32_t* success); + static NaClSrpcError PPB_Instance_IsFullFrame( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t* is_full_frame); + + private: + PpbInstanceRpcClient(); + PpbInstanceRpcClient(const PpbInstanceRpcClient&); + void operator=(const PpbInstanceRpcClient); +}; // class PpbInstanceRpcClient + +class PpbMessagingRpcClient { + public: + static NaClSrpcError PPB_Messaging_PostMessage( + NaClSrpcChannel* channel, + PP_Instance instance, + nacl_abi_size_t message_bytes, char* message); + + private: + PpbMessagingRpcClient(); + PpbMessagingRpcClient(const PpbMessagingRpcClient&); + void operator=(const PpbMessagingRpcClient); +}; // class PpbMessagingRpcClient + +class PpbPdfRpcClient { + public: + static NaClSrpcError PPB_PDF_GetLocalizedString( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t string_id, + nacl_abi_size_t* string_bytes, char* string); + static NaClSrpcError PPB_PDF_GetResourceImage( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t image_id, + PP_Resource* image); + static NaClSrpcError PPB_PDF_GetFontFileWithFallback( + NaClSrpcChannel* channel, + PP_Instance instance, + nacl_abi_size_t description_bytes, char* description, + nacl_abi_size_t face_bytes, char* face, + int32_t charset, + PP_Resource* font); + static NaClSrpcError PPB_PDF_GetFontTableForPrivateFontFile( + NaClSrpcChannel* channel, + PP_Resource font_file, + int32_t table, + nacl_abi_size_t* output_bytes, char* output, + int32_t* success); + static NaClSrpcError PPB_PDF_SearchString( + NaClSrpcChannel* channel, + PP_Instance instance, + nacl_abi_size_t string_bytes, char* string, + nacl_abi_size_t term_bytes, char* term, + int32_t case_sensitive, + nacl_abi_size_t* results_bytes, char* results, + int32_t* count); + static NaClSrpcError PPB_PDF_DidStartLoading( + NaClSrpcChannel* channel, + PP_Instance instance); + static NaClSrpcError PPB_PDF_DidStopLoading( + NaClSrpcChannel* channel, + PP_Instance instance); + static NaClSrpcError PPB_PDF_SetContentRestriction( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t restrictions); + static NaClSrpcError PPB_PDF_HistogramPDFPageCount( + NaClSrpcChannel* channel, + int32_t count); + static NaClSrpcError PPB_PDF_UserMetricsRecordAction( + NaClSrpcChannel* channel, + nacl_abi_size_t action_bytes, char* action); + static NaClSrpcError PPB_PDF_HasUnsupportedFeature( + NaClSrpcChannel* channel, + PP_Instance instance); + static NaClSrpcError PPB_PDF_SaveAs( + NaClSrpcChannel* channel, + PP_Instance instance); + + private: + PpbPdfRpcClient(); + PpbPdfRpcClient(const PpbPdfRpcClient&); + void operator=(const PpbPdfRpcClient); +}; // class PpbPdfRpcClient + +class PpbScrollbarRpcClient { + public: + static NaClSrpcError PPB_Scrollbar_Create( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t vertical, + PP_Resource* scrollbar); + static NaClSrpcError PPB_Scrollbar_IsScrollbar( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* is_scrollbar); + static NaClSrpcError PPB_Scrollbar_IsOverlay( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* is_overlay); + static NaClSrpcError PPB_Scrollbar_GetThickness( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* thickness); + static NaClSrpcError PPB_Scrollbar_GetValue( + NaClSrpcChannel* channel, + PP_Resource scrollbar, + int32_t* value); + static NaClSrpcError PPB_Scrollbar_SetValue( + NaClSrpcChannel* channel, + PP_Resource scrollbar, + int32_t value); + static NaClSrpcError PPB_Scrollbar_SetDocumentSize( + NaClSrpcChannel* channel, + PP_Resource scrollbar, + int32_t size); + static NaClSrpcError PPB_Scrollbar_SetTickMarks( + NaClSrpcChannel* channel, + PP_Resource scrollbar, + nacl_abi_size_t tick_marks_bytes, char* tick_marks, + int32_t count); + static NaClSrpcError PPB_Scrollbar_ScrollBy( + NaClSrpcChannel* channel, + PP_Resource scrollbar, + int32_t unit, + int32_t multiplier); + + private: + PpbScrollbarRpcClient(); + PpbScrollbarRpcClient(const PpbScrollbarRpcClient&); + void operator=(const PpbScrollbarRpcClient); +}; // class PpbScrollbarRpcClient + +class PpbTestingRpcClient { + public: + static NaClSrpcError PPB_Testing_ReadImageData( + NaClSrpcChannel* channel, + PP_Resource device_context_2d, + PP_Resource image, + nacl_abi_size_t top_left_bytes, char* top_left, + int32_t* success); + static NaClSrpcError PPB_Testing_RunMessageLoop( + NaClSrpcChannel* channel, + PP_Instance instance); + static NaClSrpcError PPB_Testing_QuitMessageLoop( + NaClSrpcChannel* channel, + PP_Instance instance); + static NaClSrpcError PPB_Testing_GetLiveObjectsForInstance( + NaClSrpcChannel* channel, + PP_Instance instance, + int32_t* live_object_count); + + private: + PpbTestingRpcClient(); + PpbTestingRpcClient(const PpbTestingRpcClient&); + void operator=(const PpbTestingRpcClient); +}; // class PpbTestingRpcClient + +class PpbURLLoaderRpcClient { + public: + static NaClSrpcError PPB_URLLoader_Create( + NaClSrpcChannel* channel, + PP_Instance instance, + PP_Resource* resource); + static NaClSrpcError PPB_URLLoader_IsURLLoader( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* is_url_loader); + static NaClSrpcError PPB_URLLoader_Open( + NaClSrpcChannel* channel, + PP_Resource loader, + PP_Resource request, + int32_t callback_id, + int32_t* pp_error); + static NaClSrpcError PPB_URLLoader_FollowRedirect( + NaClSrpcChannel* channel, + PP_Resource loader, + int32_t callback_id, + int32_t* pp_error); + static NaClSrpcError PPB_URLLoader_GetUploadProgress( + NaClSrpcChannel* channel, + PP_Resource loader, + int64_t* bytes_sent, + int64_t* total_bytes_to_be_sent, + int32_t* success); + static NaClSrpcError PPB_URLLoader_GetDownloadProgress( + NaClSrpcChannel* channel, + PP_Resource loader, + int64_t* bytes_received, + int64_t* total_bytes_to_be_received, + int32_t* success); + static NaClSrpcError PPB_URLLoader_GetResponseInfo( + NaClSrpcChannel* channel, + PP_Resource loader, + PP_Resource* response); + static NaClSrpcError PPB_URLLoader_ReadResponseBody( + NaClSrpcChannel* channel, + PP_Resource loader, + int32_t bytes_to_read, + int32_t callback_id, + nacl_abi_size_t* buffer_bytes, char* buffer, + int32_t* pp_error_or_bytes); + static NaClSrpcError PPB_URLLoader_FinishStreamingToFile( + NaClSrpcChannel* channel, + PP_Resource loader, + int32_t callback_id, + int32_t* pp_error); + static NaClSrpcError PPB_URLLoader_Close( + NaClSrpcChannel* channel, + PP_Resource loader); + + private: + PpbURLLoaderRpcClient(); + PpbURLLoaderRpcClient(const PpbURLLoaderRpcClient&); + void operator=(const PpbURLLoaderRpcClient); +}; // class PpbURLLoaderRpcClient + +class PpbURLRequestInfoRpcClient { + public: + static NaClSrpcError PPB_URLRequestInfo_Create( + NaClSrpcChannel* channel, + PP_Instance instance, + PP_Resource* resource); + static NaClSrpcError PPB_URLRequestInfo_IsURLRequestInfo( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* success); + static NaClSrpcError PPB_URLRequestInfo_SetProperty( + NaClSrpcChannel* channel, + PP_Resource request, + int32_t property, + nacl_abi_size_t value_bytes, char* value, + int32_t* success); + static NaClSrpcError PPB_URLRequestInfo_AppendDataToBody( + NaClSrpcChannel* channel, + PP_Resource request, + nacl_abi_size_t data_bytes, char* data, + int32_t* success); + static NaClSrpcError PPB_URLRequestInfo_AppendFileToBody( + NaClSrpcChannel* channel, + PP_Resource request, + PP_Resource file_ref, + int64_t start_offset, + int64_t number_of_bytes, + double expected_last_modified_time, + int32_t* success); + + private: + PpbURLRequestInfoRpcClient(); + PpbURLRequestInfoRpcClient(const PpbURLRequestInfoRpcClient&); + void operator=(const PpbURLRequestInfoRpcClient); +}; // class PpbURLRequestInfoRpcClient + +class PpbURLResponseInfoRpcClient { + public: + static NaClSrpcError PPB_URLResponseInfo_IsURLResponseInfo( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* success); + static NaClSrpcError PPB_URLResponseInfo_GetProperty( + NaClSrpcChannel* channel, + PP_Resource response, + int32_t property, + nacl_abi_size_t* value_bytes, char* value); + static NaClSrpcError PPB_URLResponseInfo_GetBodyAsFileRef( + NaClSrpcChannel* channel, + PP_Resource response, + PP_Resource* file_ref); + + private: + PpbURLResponseInfoRpcClient(); + PpbURLResponseInfoRpcClient(const PpbURLResponseInfoRpcClient&); + void operator=(const PpbURLResponseInfoRpcClient); +}; // class PpbURLResponseInfoRpcClient + +class PpbWidgetRpcClient { + public: + static NaClSrpcError PPB_Widget_IsWidget( + NaClSrpcChannel* channel, + PP_Resource resource, + int32_t* is_widget); + static NaClSrpcError PPB_Widget_Paint( + NaClSrpcChannel* channel, + PP_Resource widget, + nacl_abi_size_t rect_bytes, char* rect, + PP_Resource image, + int32_t* success); + static NaClSrpcError PPB_Widget_HandleEvent( + NaClSrpcChannel* channel, + PP_Resource widget, + PP_Resource event, + int32_t* handled); + static NaClSrpcError PPB_Widget_GetLocation( + NaClSrpcChannel* channel, + PP_Resource widget, + nacl_abi_size_t* location_bytes, char* location, + int32_t* visible); + static NaClSrpcError PPB_Widget_SetLocation( + NaClSrpcChannel* channel, + PP_Resource widget, + nacl_abi_size_t location_bytes, char* location); + + private: + PpbWidgetRpcClient(); + PpbWidgetRpcClient(const PpbWidgetRpcClient&); + void operator=(const PpbWidgetRpcClient); +}; // class PpbWidgetRpcClient + +class PpbZoomRpcClient { + public: + static NaClSrpcError PPB_Zoom_ZoomChanged( + NaClSrpcChannel* channel, + PP_Instance instance, + double factor); + static NaClSrpcError PPB_Zoom_ZoomLimitsChanged( + NaClSrpcChannel* channel, + PP_Instance instance, + double minimum_factor, + double maximum_factor); + + private: + PpbZoomRpcClient(); + PpbZoomRpcClient(const PpbZoomRpcClient&); + void operator=(const PpbZoomRpcClient); +}; // class PpbZoomRpcClient + + + + +#endif // GEN_PPAPI_PROXY_PPB_RPC_H_ + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/untrusted/srpcgen/ppp_rpc.h b/ppapi/native_client/src/shared/ppapi_proxy/untrusted/srpcgen/ppp_rpc.h new file mode 100644 index 0000000..2cfc560d --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/untrusted/srpcgen/ppp_rpc.h @@ -0,0 +1,278 @@ +// 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. +// +// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING +// +// Automatically generated code. See srpcgen.py +// +// NaCl Simple Remote Procedure Call interface abstractions. + +#ifndef GEN_PPAPI_PROXY_PPP_RPC_H_ +#define GEN_PPAPI_PROXY_PPP_RPC_H_ + +#ifndef __native_client__ +#include "native_client/src/include/portability.h" +#endif // __native_client__ +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_resource.h" + +class CompletionCallbackRpcServer { + public: + static void RunCompletionCallback( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + int32_t callback_id, + int32_t result, + nacl_abi_size_t read_buffer_bytes, char* read_buffer); + + private: + CompletionCallbackRpcServer(); + CompletionCallbackRpcServer(const CompletionCallbackRpcServer&); + void operator=(const CompletionCallbackRpcServer); +}; // class CompletionCallbackRpcServer + +class PppRpcServer { + public: + static void PPP_InitializeModule( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + int32_t pid, + PP_Module module, + NaClSrpcImcDescType upcall_channel_desc, + char* service_description, + int32_t* nacl_pid, + int32_t* success); + static void PPP_ShutdownModule( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done); + static void PPP_GetInterface( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + char* interface_name, + int32_t* exports_interface_name); + + private: + PppRpcServer(); + PppRpcServer(const PppRpcServer&); + void operator=(const PppRpcServer); +}; // class PppRpcServer + +class PppAudioRpcServer { + public: + static void PPP_Audio_StreamCreated( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + NaClSrpcImcDescType out_shm, + int32_t out_shm_size, + NaClSrpcImcDescType out_socket); + + private: + PppAudioRpcServer(); + PppAudioRpcServer(const PppAudioRpcServer&); + void operator=(const PppAudioRpcServer); +}; // class PppAudioRpcServer + +class PppFindRpcServer { + public: + static void PPP_Find_StartFind( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + nacl_abi_size_t text_bytes, char* text, + int32_t case_sensitive, + int32_t* supports_find); + static void PPP_Find_SelectFindResult( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t forward); + static void PPP_Find_StopFind( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance); + + private: + PppFindRpcServer(); + PppFindRpcServer(const PppFindRpcServer&); + void operator=(const PppFindRpcServer); +}; // class PppFindRpcServer + +class PppInputEventRpcServer { + public: + static void PPP_InputEvent_HandleInputEvent( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + PP_Resource resource, + nacl_abi_size_t event_data_bytes, char* event_data, + nacl_abi_size_t character_text_bytes, char* character_text, + int32_t* handled); + + private: + PppInputEventRpcServer(); + PppInputEventRpcServer(const PppInputEventRpcServer&); + void operator=(const PppInputEventRpcServer); +}; // class PppInputEventRpcServer + +class PppInstanceRpcServer { + public: + static void PPP_Instance_DidCreate( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t argc, + nacl_abi_size_t argn_bytes, char* argn, + nacl_abi_size_t argv_bytes, char* argv, + int32_t* success); + static void PPP_Instance_DidDestroy( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance); + static void PPP_Instance_DidChangeView( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + nacl_abi_size_t position_bytes, int32_t* position, + nacl_abi_size_t clip_bytes, int32_t* clip); + static void PPP_Instance_DidChangeFocus( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + bool has_focus); + static void PPP_Instance_HandleDocumentLoad( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + PP_Resource url_loader, + int32_t* success); + + private: + PppInstanceRpcServer(); + PppInstanceRpcServer(const PppInstanceRpcServer&); + void operator=(const PppInstanceRpcServer); +}; // class PppInstanceRpcServer + +class PppMessagingRpcServer { + public: + static void PPP_Messaging_HandleMessage( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + nacl_abi_size_t message_bytes, char* message); + + private: + PppMessagingRpcServer(); + PppMessagingRpcServer(const PppMessagingRpcServer&); + void operator=(const PppMessagingRpcServer); +}; // class PppMessagingRpcServer + +class PppPrintingRpcServer { + public: + static void PPP_Printing_QuerySupportedFormats( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + nacl_abi_size_t* formats_bytes, char* formats, + int32_t* format_count); + static void PPP_Printing_Begin( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + nacl_abi_size_t print_settings_bytes, char* print_settings, + int32_t* pages_required); + static void PPP_Printing_PrintPages( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + nacl_abi_size_t page_ranges_bytes, char* page_ranges, + int32_t page_range_count, + PP_Resource* image_data); + static void PPP_Printing_End( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance); + + private: + PppPrintingRpcServer(); + PppPrintingRpcServer(const PppPrintingRpcServer&); + void operator=(const PppPrintingRpcServer); +}; // class PppPrintingRpcServer + +class PppScrollbarRpcServer { + public: + static void PPP_Scrollbar_ValueChanged( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + PP_Resource scrollbar, + int32_t value); + static void PPP_Scrollbar_OverlayChanged( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + PP_Resource scrollbar, + int32_t overlay); + + private: + PppScrollbarRpcServer(); + PppScrollbarRpcServer(const PppScrollbarRpcServer&); + void operator=(const PppScrollbarRpcServer); +}; // class PppScrollbarRpcServer + +class PppSelectionRpcServer { + public: + static void PPP_Selection_GetSelectedText( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + int32_t html, + nacl_abi_size_t* selected_text_bytes, char* selected_text); + + private: + PppSelectionRpcServer(); + PppSelectionRpcServer(const PppSelectionRpcServer&); + void operator=(const PppSelectionRpcServer); +}; // class PppSelectionRpcServer + +class PppWidgetRpcServer { + public: + static void PPP_Widget_Invalidate( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + PP_Resource widget, + nacl_abi_size_t dirty_rect_bytes, char* dirty_rect); + + private: + PppWidgetRpcServer(); + PppWidgetRpcServer(const PppWidgetRpcServer&); + void operator=(const PppWidgetRpcServer); +}; // class PppWidgetRpcServer + +class PppZoomRpcServer { + public: + static void PPP_Zoom_Zoom( + NaClSrpcRpc* rpc, + NaClSrpcClosure* done, + PP_Instance instance, + double factor, + int32_t text_only); + + private: + PppZoomRpcServer(); + PppZoomRpcServer(const PppZoomRpcServer&); + void operator=(const PppZoomRpcServer); +}; // class PppZoomRpcServer + +class PppRpcs { + public: + static NaClSrpcHandlerDesc srpc_methods[]; +}; // class PppRpcs + + +#endif // GEN_PPAPI_PROXY_PPP_RPC_H_ + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/untrusted/srpcgen/upcall.h b/ppapi/native_client/src/shared/ppapi_proxy/untrusted/srpcgen/upcall.h new file mode 100644 index 0000000..027b57b --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/untrusted/srpcgen/upcall.h @@ -0,0 +1,40 @@ +// 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. +// +// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING +// +// Automatically generated code. See srpcgen.py +// +// NaCl Simple Remote Procedure Call interface abstractions. + +#ifndef GEN_PPAPI_PROXY_UPCALL_H_ +#define GEN_PPAPI_PROXY_UPCALL_H_ + +#ifndef __native_client__ +#include "native_client/src/include/portability.h" +#endif // __native_client__ +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_resource.h" + +class PppUpcallRpcClient { + public: + static NaClSrpcError PPB_Core_CallOnMainThread( + NaClSrpcChannel* channel, + int32_t delay_in_milliseconds, + int32_t callback_id, + int32_t result); + + private: + PppUpcallRpcClient(); + PppUpcallRpcClient(const PppUpcallRpcClient&); + void operator=(const PppUpcallRpcClient); +}; // class PppUpcallRpcClient + + + + +#endif // GEN_PPAPI_PROXY_UPCALL_H_ + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/upcall.srpc b/ppapi/native_client/src/shared/ppapi_proxy/upcall.srpc new file mode 100755 index 0000000..f6afbae --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/upcall.srpc @@ -0,0 +1,18 @@ +# Copyright (c) 2010 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. + +# RPC methods handled by the upcall channel instead of the main channel. +{ + 'name': 'PppUpcallRpc', + 'rpcs': [ + # Implements work scheduling on the main thread after a delay. + {'name': 'PPB_Core_CallOnMainThread', + 'inputs': [['delay_in_milliseconds', 'int32_t'], + ['callback_id', 'int32_t'], # PP_CompletionCallback + ['result', 'int32_t'], # int32_t + ], + 'outputs': [] + }, + ] +} diff --git a/ppapi/native_client/src/shared/ppapi_proxy/upcall_client.cc b/ppapi/native_client/src/shared/ppapi_proxy/upcall_client.cc new file mode 100644 index 0000000..6b174ff --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/upcall_client.cc @@ -0,0 +1,40 @@ +// 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. +// +// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING +// +// Automatically generated code. See srpcgen.py +// +// NaCl Simple Remote Procedure Call interface abstractions. + +#include "untrusted/srpcgen/upcall.h" +#ifdef __native_client__ +#ifndef UNREFERENCED_PARAMETER +#define UNREFERENCED_PARAMETER(P) do { (void) P; } while (0) +#endif // UNREFERENCED_PARAMETER +#else +#include "native_client/src/include/portability.h" +#endif // __native_client__ +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_resource.h" + +NaClSrpcError PppUpcallRpcClient::PPB_Core_CallOnMainThread( + NaClSrpcChannel* channel, + int32_t delay_in_milliseconds, + int32_t callback_id, + int32_t result) { + NaClSrpcError retval; + retval = NaClSrpcInvokeBySignature( + channel, + "PPB_Core_CallOnMainThread:iii:", + delay_in_milliseconds, + callback_id, + result + ); + return retval; +} + + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/upcall_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/upcall_server.cc new file mode 100644 index 0000000..bf7ab73 --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/upcall_server.cc @@ -0,0 +1,48 @@ +// 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. +// +// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING +// +// Automatically generated code. See srpcgen.py +// +// NaCl Simple Remote Procedure Call interface abstractions. + +#include "trusted/srpcgen/upcall.h" +#ifdef __native_client__ +#ifndef UNREFERENCED_PARAMETER +#define UNREFERENCED_PARAMETER(P) do { (void) P; } while (0) +#endif // UNREFERENCED_PARAMETER +#else +#include "native_client/src/include/portability.h" +#endif // __native_client__ +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_resource.h" + +namespace { + +static void PPB_Core_CallOnMainThreadDispatcher( + NaClSrpcRpc* rpc, + NaClSrpcArg** inputs, + NaClSrpcArg** outputs, + NaClSrpcClosure* done +) { + UNREFERENCED_PARAMETER(outputs); + PppUpcallRpcServer::PPB_Core_CallOnMainThread( + rpc, + done, + inputs[0]->u.ival, + inputs[1]->u.ival, + inputs[2]->u.ival + ); +} + +} // namespace + +NaClSrpcHandlerDesc PpbUpcalls::srpc_methods[] = { + { "PPB_Core_CallOnMainThread:iii:", PPB_Core_CallOnMainThreadDispatcher }, + { NULL, NULL } +}; + diff --git a/ppapi/native_client/src/shared/ppapi_proxy/utility.cc b/ppapi/native_client/src/shared/ppapi_proxy/utility.cc new file mode 100644 index 0000000..928708c --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/utility.cc @@ -0,0 +1,70 @@ +/* + * 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/utility.h" + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/src/include/nacl_assert.h" + +namespace ppapi_proxy { + +const int foo = 5; + +void DebugPrintf(const char* format, ...) { + static bool printf_enabled = (getenv("NACL_PPAPI_PROXY_DEBUG") != NULL); + if (printf_enabled) { + va_list argptr; + va_start(argptr, format); +#ifdef __native_client__ + fprintf(stdout, "PPAPI_PROXY_PLUGIN : "); +#else + fprintf(stdout, "PPAPI_PROXY_BROWSER: "); +#endif + vfprintf(stdout, format, argptr); + va_end(argptr); + fflush(stdout); + } +} + +bool StringIsUtf8(const char* data, uint32_t len) { + for (uint32_t i = 0; i < len; i++) { + if ((data[i] & 0x80) == 0) { + // Single-byte symbol. + continue; + } else if ((data[i] & 0xc0) == 0x80) { + // Invalid first byte. + DebugPrintf("Invalid first byte %02x\n", data[i]); + return false; + } + // This is a multi-byte symbol. + DebugPrintf("Multi-byte %02x\n", data[i]); + // Discard the uppermost bit. The remaining high-order bits are the + // unary count of continuation bytes (up to 5 of them). + char first = data[i] << 1; + uint32_t continuation_bytes = 0; + const uint32_t kMaxContinuationBytes = 5; + while (first & 0x80) { + if (++i >= len) { + DebugPrintf("String ended before enough continuation bytes" + "were found.\n"); + return false; + } else if (++continuation_bytes > kMaxContinuationBytes) { + DebugPrintf("Too many continuation bytes were requested.\n"); + return false; + } else if ((data[i] & 0xc0) != 0x80) { + DebugPrintf("Invalid continuation byte.\n"); + return false; + } + first <<= 1; + } + } + return true; +} + +} // namespace ppapi_proxy diff --git a/ppapi/native_client/src/shared/ppapi_proxy/utility.h b/ppapi/native_client/src/shared/ppapi_proxy/utility.h new file mode 100644 index 0000000..55e914a --- /dev/null +++ b/ppapi/native_client/src/shared/ppapi_proxy/utility.h @@ -0,0 +1,23 @@ +/* + * 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. + */ + +#ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_UTILITY_H_ +#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_UTILITY_H_ + +#include "native_client/src/include/nacl_assert.h" +#include "native_client/src/shared/platform/nacl_check.h" + +namespace ppapi_proxy { + +void DebugPrintf(const char* format, ...); + +// Check to see if |data| points to a valid UTF8 string. Checks at most |len| +// characters. See http://tools.ietf.org/html/rfc3629 for details. +bool StringIsUtf8(const char* data, uint32_t len); + +} // namespace ppapi_proxy + +#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_UTILITY_H_ diff --git a/ppapi/native_client/src/trusted/plugin/arch_arm/sandbox_isa.cc b/ppapi/native_client/src/trusted/plugin/arch_arm/sandbox_isa.cc new file mode 100644 index 0000000..d5c6041 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/arch_arm/sandbox_isa.cc @@ -0,0 +1,18 @@ +// Copyright 2010 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/trusted/plugin/nexe_arch.h" + +namespace { +// The list of supported ISA strings for ARM. See issue: +// http://code.google.com/p/nativeclient/issues/detail?id=1040 for more +// information. Note that these string are to be case-insensitive compared. +const char* const kNexeArchARM = "arm"; +} // namespace + +namespace plugin { +const char* GetSandboxISA() { + return kNexeArchARM; +} +} // namespace plugin diff --git a/ppapi/native_client/src/trusted/plugin/arch_x86/sandbox_isa.cc b/ppapi/native_client/src/trusted/plugin/arch_x86/sandbox_isa.cc new file mode 100644 index 0000000..f901ec64 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/arch_x86/sandbox_isa.cc @@ -0,0 +1,26 @@ +// Copyright 2010 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/trusted/plugin/nexe_arch.h" +#include "native_client/src/trusted/platform_qualify/nacl_os_qualify.h" + +namespace { +// The list of supported ISA strings for x86. See issue: +// http://code.google.com/p/nativeclient/issues/detail?id=1040 for more +// information. Note that these string are to be case-insensitive compared. +const char* const kNexeArchX86_32 = "x86-32"; +const char* const kNexeArchX86_64 = "x86-64"; +} // namespace + +namespace plugin { +const char* GetSandboxISA() { +#if defined(NACL_ARCH_CPU_X86_64) && (defined(NACL_LINUX) || defined(NACL_OSX)) + return kNexeArchX86_64; // 64-bit Linux or Mac. +#else + return NaClOsIs64BitWindows() == 1 + ? kNexeArchX86_64 // 64-bit Windows (Chrome, Firefox) + : kNexeArchX86_32; // everything else. +#endif +} +} // namespace plugin diff --git a/ppapi/native_client/src/trusted/plugin/array_ppapi.cc b/ppapi/native_client/src/trusted/plugin/array_ppapi.cc new file mode 100644 index 0000000..9f39e1e --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/array_ppapi.cc @@ -0,0 +1,28 @@ +// 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 <assert.h> + +#include "native_client/src/include/nacl_string.h" +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/trusted/plugin/utility.h" +#include "native_client/src/trusted/plugin/array_ppapi.h" + + +namespace plugin { + +ArrayPpapi::ArrayPpapi(Plugin* instance) { + PLUGIN_PRINTF(("ArrayPpapi::ArrayPpapi (this=%p, instance=%p)\n", + static_cast<void*>(this), static_cast<void*>(instance))); + pp::VarPrivate window = instance->GetWindowObject(); + PLUGIN_PRINTF(("ArrayPpapi::ArrayPpapi (window=%d)\n", + !window.is_undefined())); + js_array_ = window.Call(pp::Var("eval"), pp::Var("new Array;")); + PLUGIN_PRINTF(("ArrayPpapi::ArrayPpapi (js_array_=%d)\n", + !js_array_.is_undefined())); + assert(!js_array_.is_undefined()); +} + +} // namespace plugin diff --git a/ppapi/native_client/src/trusted/plugin/array_ppapi.h b/ppapi/native_client/src/trusted/plugin/array_ppapi.h new file mode 100644 index 0000000..60d6db2 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/array_ppapi.h @@ -0,0 +1,60 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_ARRAY_PPAPI_H_ +#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_ARRAY_PPAPI_H_ + +#include <vector> + +#include "native_client/src/include/checked_cast.h" +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/trusted/plugin/plugin.h" +#include "ppapi/cpp/dev/scriptable_object_deprecated.h" +#include "ppapi/cpp/instance.h" +#include "ppapi/cpp/private/var_private.h" + +namespace plugin { + +// Wraps a JavaScript array where each element is an indexed property. +// Can be used to represent single arguments and return values of array type +// as well as multiple return values from invoking SRPC methods. +class ArrayPpapi : public pp::deprecated::ScriptableObject { + public: + explicit ArrayPpapi(Plugin* instance); + virtual ~ArrayPpapi() {} + + virtual bool HasProperty(const pp::Var& name, pp::Var* exception) { + return js_array_.HasProperty(name, exception); + } + virtual pp::Var GetProperty(const pp::Var& name, pp::Var* exception) { + return js_array_.GetProperty(name, exception); + } + virtual void GetAllPropertyNames(std::vector<pp::Var>* properties, + pp::Var* exception) { + js_array_.GetAllPropertyNames(properties, exception); + } + virtual void SetProperty(const pp::Var& name, + const pp::Var& value, pp::Var* exception) { + js_array_.SetProperty(name, value, exception); + } + virtual void RemoveProperty(const pp::Var& name, pp::Var* exception) { + js_array_.RemoveProperty(name, exception); + } + virtual pp::Var Call(const pp::Var& method_name, + const std::vector<pp::Var>& args, pp::Var* exception) { + // Assuming the number of arguments will fit into 32 bits. + uint32_t argc = nacl::assert_cast<uint32_t>(args.size()); + pp::Var* argv = const_cast<pp::Var*>(&args[0]); // elements are contiguous + return js_array_.Call(method_name, argc, argv, exception); + } + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(ArrayPpapi); + + pp::VarPrivate js_array_; +}; + +} // namespace plugin + +#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_ARRAY_PPAPI_H_ diff --git a/ppapi/native_client/src/trusted/plugin/browser_interface.cc b/ppapi/native_client/src/trusted/plugin/browser_interface.cc new file mode 100644 index 0000000..79eea57 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/browser_interface.cc @@ -0,0 +1,69 @@ +// 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 <assert.h> + +#include "native_client/src/trusted/plugin/browser_interface.h" + +#include "native_client/src/include/checked_cast.h" +#include "native_client/src/include/elf.h" +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/trusted/plugin/scriptable_handle.h" + +#include "ppapi/c/dev/ppb_console_dev.h" +#include "ppapi/c/ppb_var.h" +#include "ppapi/cpp/module.h" +#include "ppapi/cpp/private/instance_private.h" +#include "ppapi/cpp/private/var_private.h" + +using nacl::assert_cast; + +namespace plugin { + +uintptr_t BrowserInterface::StringToIdentifier(const nacl::string& str) { + StringToIdentifierMap::iterator iter = string_to_identifier_map_.find(str); + if (iter == string_to_identifier_map_.end()) { + uintptr_t id = next_identifier++; + string_to_identifier_map_.insert(make_pair(str, id)); + identifier_to_string_map_.insert(make_pair(id, str)); + return id; + } + return string_to_identifier_map_[str]; +} + + +nacl::string BrowserInterface::IdentifierToString(uintptr_t ident) { + assert(identifier_to_string_map_.find(ident) != + identifier_to_string_map_.end()); + return identifier_to_string_map_[ident]; +} + + +void BrowserInterface::AddToConsole(pp::InstancePrivate* instance, + const nacl::string& text) { + pp::Module* module = pp::Module::Get(); + const PPB_Var* var_interface = + static_cast<const struct PPB_Var*>( + module->GetBrowserInterface(PPB_VAR_INTERFACE)); + nacl::string prefix_string("NativeClient"); + PP_Var prefix = + var_interface->VarFromUtf8(module->pp_module(), + prefix_string.c_str(), + static_cast<uint32_t>(prefix_string.size())); + PP_Var str = var_interface->VarFromUtf8(module->pp_module(), + text.c_str(), + static_cast<uint32_t>(text.size())); + const PPB_Console_Dev* console_interface = + static_cast<const struct PPB_Console_Dev*>( + module->GetBrowserInterface(PPB_CONSOLE_DEV_INTERFACE)); + console_interface->LogWithSource(instance->pp_instance(), + PP_LOGLEVEL_LOG, + prefix, + str); + var_interface->Release(prefix); + var_interface->Release(str); +} + +} // namespace plugin diff --git a/ppapi/native_client/src/trusted/plugin/browser_interface.h b/ppapi/native_client/src/trusted/plugin/browser_interface.h new file mode 100644 index 0000000..4866372 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/browser_interface.h @@ -0,0 +1,57 @@ +/* + * 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. + */ + + +// Interface for browser interaction + +#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_BROWSER_INTERFACE_H_ +#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_BROWSER_INTERFACE_H_ + +#include <stdio.h> +#include <map> + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/nacl_string.h" +#include "native_client/src/include/portability.h" +#include "ppapi/cpp/instance.h" + +namespace pp { +class InstancePrivate; +} // namespace + +namespace plugin { + +// BrowserInterface represents the interface to the browser from the plugin. +// I.e., when the plugin needs to request an alert, it uses these interfaces. +class BrowserInterface { + public: + BrowserInterface() : next_identifier(0) {} + ~BrowserInterface() { } + + // Functions for communication with the browser. + + // Convert a string to an identifier. + uintptr_t StringToIdentifier(const nacl::string& str); + // Convert an identifier to a string. + nacl::string IdentifierToString(uintptr_t ident); + + // Write to the JavaScript console. + void AddToConsole(pp::InstancePrivate* instance, const nacl::string& text); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(BrowserInterface); + + // Map strings used for property and method names to unique ids and back. + typedef std::map<nacl::string, uintptr_t> StringToIdentifierMap; + typedef std::map<uintptr_t, nacl::string> IdentifierToStringMap; + StringToIdentifierMap string_to_identifier_map_; + IdentifierToStringMap identifier_to_string_map_; + uintptr_t next_identifier; // will be incremented once used +}; + +} // namespace plugin + +#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_BROWSER_INTERFACE_H_ diff --git a/ppapi/native_client/src/trusted/plugin/browser_utils.cc b/ppapi/native_client/src/trusted/plugin/browser_utils.cc new file mode 100644 index 0000000..5268bce --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/browser_utils.cc @@ -0,0 +1,20 @@ +/* + * 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. + */ + + +// Portable interface for browser interaction - API invariant portions. + +#include "base/rand_util_c.h" + +#include "native_client/src/trusted/plugin/nacl_entry_points.h" + + +extern "C" { + int GetUrandomFD(void) { + return get_urandom_fd(); + } +} + diff --git a/ppapi/native_client/src/trusted/plugin/build.scons b/ppapi/native_client/src/trusted/plugin/build.scons new file mode 100644 index 0000000..ffa46c9 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/build.scons @@ -0,0 +1,199 @@ +# -*- python -*- +# 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. + +# TODO(polina): for Mac build check if no longer need .r files and/or document +# target browsers for each bundle target. + +Import('env') + +if not env.Bit('mac'): + env['COMPONENT_STATIC'] = False + + +plugin_env = env.Clone() +if env.Bit('linux'): + plugin_env.Append( + CCFLAGS=['-fPIC', '-Wno-long-long',], + CPPDEFINES = ['XP_UNIX', 'MOZ_X11'], + # Catch unresolved symbols in libraries. + LINKFLAGS=['-Wl,-z,defs'], + ) + + # We usually try to build things statically, but the plugin is a .so + plugin_env.FilterOut(LINKFLAGS=['-static']) + +if env.Bit('mac'): + plugin_env.Append( + CCFLAGS=['-Wno-long-long', + # warning: Basically all of our 2d Mac stuff is deprecated. + '-Wno-deprecated', + '-Wno-deprecated-declarations'], + CPPDEFINES = [ + 'XP_MACOSX', + 'XP_UNIX', + ['TARGET_API_MAC_CARBON', '1'], + # TODO(robertm): NO_X11 may be obsolete + 'NO_X11', + 'USE_SYSTEM_CONSOLE', + ], + FRAMEWORKS = ['Carbon'], + # TODO(jrg): it's a little awkward to, when you want a bundle: + # 1) add -bundle to your LINKFLAGS + # 2) create a "program" (which shows up in all_programs target) + # 3) create a bundle out of it, specifying the bundle extension + # Ideally that all happens inside a CompleteBundlePseudoBuilder(). + LINKFLAGS = ['-bundle', '-framework', 'Foundation'] + ) + +if env.Bit('windows'): + plugin_env.Append( + CPPDEFINES = ['XP_WIN', 'WIN32', '_WINDOWS'], + ) + +common_inputs = [ + 'array_ppapi.cc', + 'browser_interface.cc', + 'desc_based_handle.cc', + 'file_downloader.cc', + 'manifest.cc', + 'method_map.cc', + 'module_ppapi.cc', + 'nacl_subprocess.cc', + 'nexe_arch.cc', + 'plugin.cc', + 'pnacl_coordinator.cc', + 'pnacl_srpc_lib.cc', + 'scriptable_handle.cc', + 'service_runtime.cc', + 'srpc_client.cc', + 'string_encoding.cc', + 'utility.cc', + 'var_utils.cc', +] + +if env.Bit('target_x86'): + common_inputs += ['arch_x86/sandbox_isa.cc'] +elif env.Bit('target_arm'): + common_inputs += ['arch_arm/sandbox_isa.cc'] +else: + # Unrecognized architecture - this is a build failure. + print "Unrecognized architecture: %s" % env['TARGET_ARCHITECTURE'] + Return() + +# The libraries used by both the PPAPI plugin. They and the PPAPI specific +# libraries must come before OS libraries, because they may generate references +# that are resolved by the OS libraries. E.g., libplatform.a contains +# references to symbols from libcrypto.so. +common_libs = [ + 'nonnacl_util', + 'nonnacl_srpc', + 'gio_wrapped_desc', + 'nrd_xfer', + 'nacl_perf_counter', + 'nacl_base', + 'imc', + 'weak_ref', + 'platform', + 'platform_qual_lib', + 'reverse_service', + 'gio', + 'jsoncpp', + 'sel', + 'simple_service', + 'thread_interface', + 'env_cleanser', + 'nacl_error_code', +] + +os_libs = [ ] +if plugin_env.Bit('linux'): + os_libs += ['dl', 'Xt', 'X11', 'crypto'] + +if plugin_env.Bit('windows'): + os_libs += ['gdi32', 'user32', ] + + +############################################################################### +# PPAPI Plugin Build +############################################################################### + +# We build a shared library with this build script to allow easier build +# testing. This library can also be loaded into Chrome using --no-sandbox +# --register-pepper-plugins="path/to/library;application/x-nacl". +# +# The .gyp files include rules used to link the plugin statically into Chrome. +# (This is still work in progress as of mid-Nov 2010.) +# + +ppNaClPlugin = 'ppNaClPlugin' + +ppapi_libs = common_libs + [ 'ppapi_cpp', 'ppapi_browser', 'nonnacl_srpc' ] +if plugin_env['SHARED_LIBS_SPECIAL']: + plugin_env.Append(LIBS=[l + '_shared' for l in ppapi_libs] + os_libs) +else: + plugin_env.Append(LIBS=ppapi_libs + os_libs) + +if not env.Bit('mac'): # linux, windows, arm + # This builds with + # MODE=... ppNaClPlugin sel_ldr + # with the output going to + # scons-out/.../staging/libppNaClPlugin.so on Linux and + # scons-out/.../staging/ppNaClPlugin.dll on Windows. + ppapi_plugin = plugin_env.ComponentLibrary(ppNaClPlugin, + common_inputs, + no_import_lib=True) +else: # mac + # This builds with + # MODE=... scons-out/.../staging/ppNaClPlugin.bundle sel_ldr + # This places both ppNaClPlugin.bundle/ and sel_ldr into staging/. + # One must either set $NACL_SEL_LDR=path/to/sel_ldr or manually + # copy sel_ldr to path/to/ppNaClPlugin.bundle/Contents/Resources/. + # (the 2nd option has been disabled: + # see ../nonnacl_util/osx/get_plugin_dirname.mm). + REZ = '/Developer/Tools/Rez' + plugin_env.Command(target='ppNaClPlugin.rsrc', + source='osx_ppapi/ppNaClPlugin.r', + action=[Action(REZ + ' -o ${TARGET} ${SOURCE} -useDF')]) + ppapi_plugin = plugin_env.ComponentProgram(ppNaClPlugin, + common_inputs, + no_import_lib=True) + # Bundle pattern can be found in + # site_scons/site_tools/target_platform_mac.py + bundle_name = '${STAGING_DIR}/' + ppNaClPlugin + '.bundle' + plugin_env.Bundle(bundle_name, + BUNDLE_EXE = ppapi_plugin, + BUNDLE_PKGINFO_FILENAME = 0, + BUNDLE_RESOURCES = 'ppNaClPlugin.rsrc', + BUNDLE_INFO_PLIST = 'osx_ppapi/Info.plist') + +plugin_env.Alias('plugin', plugin_env.GetPPAPIPluginPath(False)) + +############################################################################### +# PPAPI Plugin Test +############################################################################### + +# Rather than link ppNaClPlugin statically, this unittest uses the dynamic +# library. Note that these tests do not yet run on ARM. +unittest_sources = ['dylib_unittest.cc', 'plugin_unittest.cc'] +if env.Bit('target_x86'): + if env.Bit('linux'): + unittest = env.ComponentProgram('ppapi_plugin_unittest', + unittest_sources, + no_import_lib=True, + EXTRA_LIBS=['dl']) + elif env.Bit('mac'): + unittest = env.ComponentProgram('ppapi_plugin_unittest', unittest_sources) + elif env.Bit('windows'): + unittest = env.ComponentProgram('ppapi_plugin_unittest', + unittest_sources, + no_import_lib=True) + node = env.CommandTest('ppapi_plugin_unittest.out', + command=[unittest, + ppapi_plugin, + env['BUILD_ISA_NAME']]) + env.AddNodeToTestSuite(node, ['small_tests'], 'run_ppapi_plugin_unittest') + + +# TODO(polina,sehr): add a test for the PPAPI plugin on ARM. diff --git a/ppapi/native_client/src/trusted/plugin/delayed_callback.h b/ppapi/native_client/src/trusted/plugin/delayed_callback.h new file mode 100644 index 0000000..bf22e2b --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/delayed_callback.h @@ -0,0 +1,70 @@ +/* + * 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. + */ + +#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_DELAYED_CALLBACK_H_ +#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_DELAYED_CALLBACK_H_ + +#include "native_client/src/include/portability.h" + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/shared/platform/nacl_check.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/cpp/completion_callback.h" + +namespace plugin { + +// Delay a "Run(PP_OK)" of a pp::CompletionCallback after exactly N time ticks +// have passed. User should not attempt to count beyond N ticks. +// It is expected that this is only counted up on "good" code paths +// (when there are no errors), so that passing along a status code of +// PP_OK makes sense. +class DelayedCallback { + public: + DelayedCallback(pp::CompletionCallback continuation, + uint32_t initial_requirement) + : required_ticks_(initial_requirement), + continuation_(continuation), + started_(false) { + } + + ~DelayedCallback() { } + + // Advance time, and run the callback if it is finally time. + // This must be run on the main thread, since pp callbacks + // must be run on the main thread anyway. We also want to + // avoid race condtions. If we want to relax the requirement, + // we could add locks and use CallOnMainThread. + void RunIfTime() { + CHECK(required_ticks_ > 0); + started_ = true; + --required_ticks_; + if (0 == required_ticks_) { + continuation_.Run(PP_OK); + } + } + + // Add another requirement before anything has run. + void IncrRequirements(uint32_t additional_requirements) { + CHECK(started_ == false); + required_ticks_ += additional_requirements; + } + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(DelayedCallback); + + // How many time ticks are left before we run the callback. + uint32_t required_ticks_; + + // The continuation to invoke when ticks passed. + pp::CompletionCallback continuation_; + + // Some sanity checking to catch when people misuse the library. + bool started_; +}; + +} // namespace plugin + +#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_DELAYED_CALLBACK_H_ diff --git a/ppapi/native_client/src/trusted/plugin/desc_based_handle.cc b/ppapi/native_client/src/trusted/plugin/desc_based_handle.cc new file mode 100644 index 0000000..c422668 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/desc_based_handle.cc @@ -0,0 +1,36 @@ +/* + * 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/trusted/plugin/browser_interface.h" +#include "native_client/src/trusted/plugin/desc_based_handle.h" +#include "native_client/src/trusted/plugin/plugin.h" + + +namespace plugin { + +DescBasedHandle::DescBasedHandle(nacl::DescWrapper* wrapper) + : wrapper_(wrapper) { + PLUGIN_PRINTF(("DescBasedHandle::DescBasedHandle (this=%p)\n", + static_cast<void*>(this))); +} + +DescBasedHandle::~DescBasedHandle() { + PLUGIN_PRINTF(("DescBasedHandle::~DescBasedHandle (this=%p)\n", + static_cast<void*>(this))); +} + +DescBasedHandle* DescBasedHandle::New(nacl::DescWrapper* wrapper) { + PLUGIN_PRINTF(("DescBasedHandle::New (wrapper=%p)\n", + static_cast<void*>(wrapper))); + + if (wrapper == NULL) { + return NULL; + } + return new DescBasedHandle(wrapper); +} + +} // namespace plugin diff --git a/ppapi/native_client/src/trusted/plugin/desc_based_handle.h b/ppapi/native_client/src/trusted/plugin/desc_based_handle.h new file mode 100644 index 0000000..3c4d2ce --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/desc_based_handle.h @@ -0,0 +1,52 @@ +/* + * 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. + */ + +// OBSOLETE -- this class provides support for passing NaClDescs between +// plugin instances. This support only exists in SRPC-mode plugins. +// TODO(polina): remove when SRPC descriptor passing is removed. + +#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_DESC_BASED_HANDLE_H_ +#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_DESC_BASED_HANDLE_H_ + +#include <stdio.h> +#include <map> + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/trusted/desc/nacl_desc_wrapper.h" +#include "native_client/src/trusted/plugin/utility.h" + +struct NaClDesc; + +namespace nacl { +class DescWrapper; +} // namespace nacl + +namespace plugin { + +class Plugin; + +// DescBasedHandles are used to convey NaClDesc objects through JavaScript. +class DescBasedHandle { + public: + // Creates a new DescBasedHandle using the specified plugin and wrapper. + // Returns NULL if either plugin or wrapper is NULL. + static DescBasedHandle* New(nacl::DescWrapper* wrapper); + ~DescBasedHandle(); + + // Because the factory ensured that wrapper was not NULL, dereferencing it + // here is always safe. + NaClDesc* desc() const { return wrapper_->desc(); } + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(DescBasedHandle); + explicit DescBasedHandle(nacl::DescWrapper* wrapper); + nacl::scoped_ptr<nacl::DescWrapper> wrapper_; +}; + +} // namespace plugin + +#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_DESC_BASED_HANDLE_H_ diff --git a/ppapi/native_client/src/trusted/plugin/dylib_unittest.cc b/ppapi/native_client/src/trusted/plugin/dylib_unittest.cc new file mode 100644 index 0000000..2172ef0 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/dylib_unittest.cc @@ -0,0 +1,41 @@ +// Copyright 2010 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/trusted/plugin/dylib_unittest.h" + +#include <stdio.h> + +#if NACL_WINDOWS +DylibHandle DylibOpen(const char* lib_path) { + return LoadLibrary(lib_path); +} + +bool DylibClose(DylibHandle dl_handle) { + return FreeLibrary(dl_handle) == TRUE; +} + +SymbolHandle GetSymbolHandle(DylibHandle dl_handle, const char* name) { + return reinterpret_cast<SymbolHandle>(GetProcAddress(dl_handle, name)); +} +#else +DylibHandle DylibOpen(const char* lib_path) { + // By using RTLD_NOW we check that all symbols are resolved before the + // dlopen completes, or it fails. + return dlopen(lib_path, RTLD_NOW | RTLD_LOCAL); +} + +bool DylibClose(DylibHandle dl_handle) { + return dlclose(dl_handle) == 0; +} + +SymbolHandle GetSymbolHandle(DylibHandle dl_handle, const char* name) { + void* sym_handle = dlsym(dl_handle, name); + char* error_string = dlerror(); + if (sym_handle == NULL || error_string != NULL) { + fprintf(stderr, "Couldn't get symbol %s: %s\n", name, error_string); + sym_handle = NULL; + } + return reinterpret_cast<SymbolHandle>(sym_handle); +} +#endif diff --git a/ppapi/native_client/src/trusted/plugin/dylib_unittest.h b/ppapi/native_client/src/trusted/plugin/dylib_unittest.h new file mode 100644 index 0000000..fa72684 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/dylib_unittest.h @@ -0,0 +1,39 @@ +// Copyright 2010 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. + +// Functions for dynamically loading the trusted plugin when running unit +// tests. + +#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_DYLIB_UNITTEST_H_ +#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_DYLIB_UNITTEST_H_ + +#if NACL_WINDOWS +#include <windows.h> +typedef HINSTANCE DylibHandle; +typedef void (*SymbolHandle)(); +#else +#include <dlfcn.h> +#include <inttypes.h> +typedef void* DylibHandle; +// uintptr_t is used here because ISO C++ won't allow casting from a void* +// (the return type of dlsym()) to a pointer-to-function. Instead, +// GetSymbolHandle() returns a uintptr_t which can then be cast into a pointer- +// to-function. This depends on uintptr_t being the same size (or larger than) +// void*. +typedef uintptr_t SymbolHandle; +#endif + +// Load the dynamic library at |lib_path|. Returns NULL on error. +DylibHandle DylibOpen(const char* lib_path); + +// Close the dynamic library and free all the system resources associated with +// it. Returns |true| on success. +bool DylibClose(DylibHandle dl_handle); + +// Return a handle to the symbol named |name| in the library represented by +// |dl_handle|. Returns NULL ff the symbol does not exist, or some other error +// occurs. +SymbolHandle GetSymbolHandle(DylibHandle dl_handle, const char* name); + +#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_DYLIB_UNITTEST_H_ diff --git a/ppapi/native_client/src/trusted/plugin/file_downloader.cc b/ppapi/native_client/src/trusted/plugin/file_downloader.cc new file mode 100644 index 0000000..4c8f476 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/file_downloader.cc @@ -0,0 +1,338 @@ +// 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/trusted/plugin/file_downloader.h" + +#include <stdio.h> +#include <string> + +#include "native_client/src/include/portability_io.h" +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/src/shared/platform/nacl_time.h" +#include "native_client/src/trusted/plugin/plugin.h" +#include "native_client/src/trusted/plugin/utility.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/ppb_file_io.h" +#include "ppapi/c/trusted/ppb_url_loader_trusted.h" +#include "ppapi/cpp/file_io.h" +#include "ppapi/cpp/file_ref.h" +#include "ppapi/cpp/url_request_info.h" +#include "ppapi/cpp/url_response_info.h" + +namespace { +const int32_t kExtensionUrlRequestStatusOk = 200; +const int32_t kDataUriRequestStatusOk = 0; +} + +namespace plugin { + +void FileDownloader::Initialize(Plugin* instance) { + PLUGIN_PRINTF(("FileDownloader::FileDownloader (this=%p)\n", + static_cast<void*>(this))); + CHECK(instance != NULL); + CHECK(instance_ == NULL); // Can only initialize once. + instance_ = instance; + callback_factory_.Initialize(this); + file_io_trusted_interface_ = static_cast<const PPB_FileIOTrusted*>( + pp::Module::Get()->GetBrowserInterface(PPB_FILEIOTRUSTED_INTERFACE)); +} + + +bool FileDownloader::Open(const nacl::string& url, + DownloadFlags flags, + const pp::CompletionCallback& callback) { + PLUGIN_PRINTF(("FileDownloader::Open (url=%s)\n", url.c_str())); + if (callback.pp_completion_callback().func == NULL || + instance_ == NULL || + file_io_trusted_interface_ == NULL) + return false; + + CHECK(instance_ != NULL); + open_time_ = NaClGetTimeOfDayMicroseconds(); + url_to_open_ = url; + url_ = url; + file_open_notify_callback_ = callback; + flags_ = flags; + buffer_.clear(); + pp::Module* module = pp::Module::Get(); + pp::URLRequestInfo url_request(instance_); + + do { + // Reset the url loader and file reader. + // Note that we have the only reference to the underlying objects, so + // this will implicitly close any pending IO and destroy them. + url_loader_ = pp::URLLoader(instance_); + url_scheme_ = instance_->GetUrlScheme(url); + bool grant_universal_access = false; + if (url_scheme_ == SCHEME_CHROME_EXTENSION) { + if (instance_->IsForeignMIMEType()) { + // This NEXE is being used as a content type handler rather than + // directly by an HTML document. In that case, the NEXE runs in the + // security context of the content it is rendering and the NEXE itself + // appears to be a cross-origin resource stored in a Chrome extension. + // We request universal access during this load so that we can read the + // NEXE. + grant_universal_access = true; + } + } else if (url_scheme_ == SCHEME_DATA) { + // TODO(elijahtaylor) Remove this when data URIs can be read without + // universal access. + if (streaming_to_buffer()) { + grant_universal_access = true; + } else { + // Open is to invoke a callback on success or failure. Schedule + // it asynchronously to follow PPAPI's convention and avoid reentrancy. + pp::Core* core = pp::Module::Get()->core(); + core->CallOnMainThread(0, callback, PP_ERROR_NOACCESS); + PLUGIN_PRINTF(("FileDownloader::Open (pp_error=PP_ERROR_NOACCESS)\n")); + return true; + } + } + + if (grant_universal_access) { + const PPB_URLLoaderTrusted* url_loaded_trusted = + static_cast<const PPB_URLLoaderTrusted*>( + module->GetBrowserInterface(PPB_URLLOADERTRUSTED_INTERFACE)); + if (url_loaded_trusted != NULL) + url_loaded_trusted->GrantUniversalAccess(url_loader_.pp_resource()); + } + + // Prepare the url request. + url_request.SetURL(url_); + + if (streaming_to_file()) { + file_reader_ = pp::FileIO(instance_); + url_request.SetStreamToFile(true); + } + } while (0); + + void (FileDownloader::*start_notify)(int32_t); + if (streaming_to_file()) + start_notify = &FileDownloader::URLLoadStartNotify; + else + start_notify = &FileDownloader::URLBufferStartNotify; + + // Request asynchronous download of the url providing an on-load callback. + // As long as this step is guaranteed to be asynchronous, we can call + // synchronously all other internal callbacks that eventually result in the + // invocation of the user callback. The user code will not be reentered. + pp::CompletionCallback onload_callback = + callback_factory_.NewRequiredCallback(start_notify); + int32_t pp_error = url_loader_.Open(url_request, onload_callback); + PLUGIN_PRINTF(("FileDownloader::Open (pp_error=%"NACL_PRId32")\n", pp_error)); + CHECK(pp_error == PP_OK_COMPLETIONPENDING); + return true; +} + +int32_t FileDownloader::GetPOSIXFileDescriptor() { + if (!streaming_to_file()) { + return NACL_NO_FILE_DESC; + } + // Use the trusted interface to get the file descriptor. + if (file_io_trusted_interface_ == NULL) { + return NACL_NO_FILE_DESC; + } + int32_t file_desc = file_io_trusted_interface_->GetOSFileDescriptor( + file_reader_.pp_resource()); + + +#if NACL_WINDOWS + // Convert the Windows HANDLE from Pepper to a POSIX file descriptor. + int32_t posix_desc = _open_osfhandle(file_desc, _O_RDWR | _O_BINARY); + if (posix_desc == -1) { + // Close the Windows HANDLE if it can't be converted. + CloseHandle(reinterpret_cast<HANDLE>(file_desc)); + return NACL_NO_FILE_DESC; + } + file_desc = posix_desc; +#endif + + return file_desc; +} + +int64_t FileDownloader::TimeSinceOpenMilliseconds() const { + int64_t now = NaClGetTimeOfDayMicroseconds(); + // If Open() wasn't called or we somehow return an earlier time now, just + // return the 0 rather than worse nonsense values. + if (open_time_ < 0 || now < open_time_) + return 0; + return (now - open_time_) / NACL_MICROS_PER_MILLI; +} + +bool FileDownloader::InitialResponseIsValid(int32_t pp_error) { + if (pp_error != PP_OK) { // Url loading failed. + file_open_notify_callback_.Run(pp_error); + return false; + } + + // Process the response, validating the headers to confirm successful loading. + pp::URLResponseInfo url_response(url_loader_.GetResponseInfo()); + if (url_response.is_null()) { + PLUGIN_PRINTF(( + "FileDownloader::InitialResponseIsValid (url_response=NULL)\n")); + file_open_notify_callback_.Run(PP_ERROR_FAILED); + return false; + } + // Note that URLs in the chrome-extension scheme produce different error + // codes than other schemes. This is because chrome-extension URLs are + // really a special kind of file scheme, and therefore do not produce HTTP + // status codes. + pp::Var full_url = url_response.GetURL(); + if (!full_url.is_string()) { + PLUGIN_PRINTF(( + "FileDownloader::InitialResponseIsValid (url is not a string)\n")); + file_open_notify_callback_.Run(PP_ERROR_FAILED); + return false; + } + bool status_ok = false; + int32_t status_code = url_response.GetStatusCode(); + switch (url_scheme_) { + case SCHEME_CHROME_EXTENSION: + PLUGIN_PRINTF(("FileDownloader::InitialResponseIsValid (chrome-extension " + "response status_code=%"NACL_PRId32")\n", status_code)); + status_ok = (status_code == kExtensionUrlRequestStatusOk); + break; + case SCHEME_DATA: + PLUGIN_PRINTF(("FileDownloader::InitialResponseIsValid (data URI " + "response status_code=%"NACL_PRId32")\n", status_code)); + status_ok = (status_code == kDataUriRequestStatusOk); + break; + case SCHEME_OTHER: + PLUGIN_PRINTF(("FileDownloader::InitialResponseIsValid (HTTP response " + "status_code=%"NACL_PRId32")\n", status_code)); + status_ok = (status_code == NACL_HTTP_STATUS_OK); + break; + } + + if (!status_ok) { + file_open_notify_callback_.Run(PP_ERROR_FAILED); + return false; + } + + return true; +} + +void FileDownloader::URLLoadStartNotify(int32_t pp_error) { + PLUGIN_PRINTF(("FileDownloader::URLLoadStartNotify (pp_error=%" + NACL_PRId32")\n", pp_error)); + + if (!InitialResponseIsValid(pp_error)) + return; + // Finish streaming the body providing an optional callback. + pp::CompletionCallback onload_callback = + callback_factory_.NewOptionalCallback( + &FileDownloader::URLLoadFinishNotify); + pp_error = url_loader_.FinishStreamingToFile(onload_callback); + bool async_notify_ok = (pp_error == PP_OK_COMPLETIONPENDING); + PLUGIN_PRINTF(("FileDownloader::URLLoadStartNotify (async_notify_ok=%d)\n", + async_notify_ok)); + if (!async_notify_ok) { + // Call manually to free allocated memory and report errors. This calls + // |file_open_notify_callback_| with |pp_error| as the parameter. + onload_callback.Run(pp_error); + } +} + +void FileDownloader::URLLoadFinishNotify(int32_t pp_error) { + PLUGIN_PRINTF(("FileDownloader::URLLoadFinishNotify (pp_error=%" + NACL_PRId32")\n", pp_error)); + if (pp_error != PP_OK) { // Streaming failed. + file_open_notify_callback_.Run(pp_error); + return; + } + + pp::URLResponseInfo url_response(url_loader_.GetResponseInfo()); + // Validated on load. + CHECK(url_response.GetStatusCode() == NACL_HTTP_STATUS_OK || + url_response.GetStatusCode() == kExtensionUrlRequestStatusOk); + + // Record the full url from the response. + pp::Var full_url = url_response.GetURL(); + PLUGIN_PRINTF(("FileDownloader::URLLoadFinishNotify (full_url=%s)\n", + full_url.DebugString().c_str())); + if (!full_url.is_string()) { + file_open_notify_callback_.Run(PP_ERROR_FAILED); + return; + } + url_ = full_url.AsString(); + + // The file is now fully downloaded. + pp::FileRef file(url_response.GetBodyAsFileRef()); + if (file.is_null()) { + PLUGIN_PRINTF(("FileDownloader::URLLoadFinishNotify (file=NULL)\n")); + file_open_notify_callback_.Run(PP_ERROR_FAILED); + return; + } + + // Open the file providing an optional callback. + pp::CompletionCallback onopen_callback = + callback_factory_.NewOptionalCallback(&FileDownloader::FileOpenNotify); + pp_error = file_reader_.Open(file, PP_FILEOPENFLAG_READ, onopen_callback); + bool async_notify_ok = (pp_error == PP_OK_COMPLETIONPENDING); + PLUGIN_PRINTF(("FileDownloader::URLLoadFinishNotify (async_notify_ok=%d)\n", + async_notify_ok)); + if (!async_notify_ok) { + // Call manually to free allocated memory and report errors. This calls + // |file_open_notify_callback_| with |pp_error| as the parameter. + onopen_callback.Run(pp_error); + } +} + +void FileDownloader::URLBufferStartNotify(int32_t pp_error) { + PLUGIN_PRINTF(("FileDownloader::URLBufferStartNotify (pp_error=%" + NACL_PRId32")\n", pp_error)); + + if (!InitialResponseIsValid(pp_error)) + return; + // Finish streaming the body asynchronously providing a callback. + pp::CompletionCallback onread_callback = + callback_factory_.NewOptionalCallback(&FileDownloader::URLReadBodyNotify); + pp_error = url_loader_.ReadResponseBody(temp_buffer_, + kTempBufferSize, + onread_callback); + bool async_notify_ok = (pp_error == PP_OK_COMPLETIONPENDING); + PLUGIN_PRINTF(("FileDownloader::URLBufferStartNotify (async_notify_ok=%d)\n", + async_notify_ok)); + if (!async_notify_ok) { + onread_callback.Run(pp_error); + } +} + +void FileDownloader::URLReadBodyNotify(int32_t pp_error) { + PLUGIN_PRINTF(("FileDownloader::URLReadBodyNotify (pp_error=%" + NACL_PRId32")\n", pp_error)); + if (pp_error < PP_OK) { + file_open_notify_callback_.Run(pp_error); + } else if (pp_error == PP_OK) { + FileOpenNotify(PP_OK); + } else { + buffer_.insert(buffer_.end(), temp_buffer_, temp_buffer_ + pp_error); + pp::CompletionCallback onread_callback = + callback_factory_.NewOptionalCallback( + &FileDownloader::URLReadBodyNotify); + pp_error = url_loader_.ReadResponseBody(temp_buffer_, + kTempBufferSize, + onread_callback); + bool async_notify_ok = (pp_error == PP_OK_COMPLETIONPENDING); + if (!async_notify_ok) { + onread_callback.Run(pp_error); + } + } +} + +void FileDownloader::FileOpenNotify(int32_t pp_error) { + PLUGIN_PRINTF(("FileDownloader::FileOpenNotify (pp_error=%"NACL_PRId32")\n", + pp_error)); + file_open_notify_callback_.Run(pp_error); +} + +bool FileDownloader::streaming_to_file() const { + return (flags_ & DOWNLOAD_TO_BUFFER) == 0; +} + +bool FileDownloader::streaming_to_buffer() const { + return (flags_ & DOWNLOAD_TO_BUFFER) == 1; +} + +} // namespace plugin diff --git a/ppapi/native_client/src/trusted/plugin/file_downloader.h b/ppapi/native_client/src/trusted/plugin/file_downloader.h new file mode 100644 index 0000000..f94d7fe8 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/file_downloader.h @@ -0,0 +1,118 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_FILE_DOWNLOADER_H_ +#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_FILE_DOWNLOADER_H_ + +#include <deque> + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/nacl_string.h" +#include "ppapi/c/trusted/ppb_file_io_trusted.h" +#include "ppapi/cpp/completion_callback.h" +#include "ppapi/cpp/file_io.h" +#include "ppapi/cpp/url_loader.h" +#include "ppapi/cpp/instance.h" + +namespace plugin { + +class Plugin; + +typedef enum { + DOWNLOAD_TO_FILE = 0 << 0, + DOWNLOAD_TO_BUFFER = 1 << 0 +} DownloadFlags; + +typedef enum { + SCHEME_CHROME_EXTENSION, + SCHEME_DATA, + SCHEME_OTHER +} UrlSchemeType; + +// A class that wraps PPAPI URLLoader and FileIO functionality for downloading +// the url into a file and providing an open file descriptor. +class FileDownloader { + public: + // Ctor initializes |instance_| to NULL, be sure to call Initialize() before + // calling Open(), or Open() will fail. + FileDownloader() + : instance_(NULL), + file_open_notify_callback_(pp::BlockUntilComplete()), + file_io_trusted_interface_(NULL), + open_time_(-1) {} + ~FileDownloader() {} + + // Initialize() can only be called once during the lifetime of this instance. + void Initialize(Plugin* instance); + + // Issues a GET on |url| downloading the response into a file. The file is + // then opened and a file descriptor is made available. + // Returns true when callback is scheduled to be called on success or failure. + // Returns false if callback is NULL, Initialize() has not been called or if + // the PPB_FileIO_Trusted interface is not available. + bool Open(const nacl::string& url, + DownloadFlags flags, + const pp::CompletionCallback& callback); + + // If downloading and opening succeeded, this returns a valid read-only + // POSIX file descriptor. On failure, the return value is an invalid + // descriptor. The file descriptor is owned by this instance, so the + // delegate does not have to close it. + int32_t GetPOSIXFileDescriptor(); + + // Returns the time delta between the call to Open() and this function. + int64_t TimeSinceOpenMilliseconds() const; + + // The value of |url_| changes over the life of this instance. When the file + // is first opened, |url_| is a copy of the URL used to open the file, which + // can be a relative URL. Once the GET request has finished, and the contents + // of the file represented by |url_| are available, |url_| is the full URL + // including the scheme, host and full path. + const nacl::string& url() const { return url_; } + + // Returns the url passed to Open(). + const nacl::string& url_to_open() const { return url_to_open_; } + + // Returns the buffer used for DOWNLOAD_TO_BUFFER mode. + const std::deque<char>& buffer() const { return buffer_; } + + bool streaming_to_file() const; + bool streaming_to_buffer() const; + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(FileDownloader); + // This class loads and opens the file in three steps for DOWNLOAD_TO_FILE: + // 1) Ask the browser to start streaming |url_| as a file. + // 2) Ask the browser to finish streaming if headers indicate success. + // 3) Ask the browser to open the file, so we can get the file descriptor. + // For DOWNLOAD_TO_BUFFER, the process is very similar: + // 1) Ask the browser to start streaming |url_| to an internal buffer. + // 2) Ask the browser to finish streaming to |temp_buffer_| on success. + // 3) Wait for streaming to finish, filling |buffer_| incrementally. + // Each step is done asynchronously using callbacks. We create callbacks + // through a factory to take advantage of ref-counting. + bool InitialResponseIsValid(int32_t pp_error); + void URLLoadStartNotify(int32_t pp_error); + void URLLoadFinishNotify(int32_t pp_error); + void URLBufferStartNotify(int32_t pp_error); + void URLReadBodyNotify(int32_t pp_error); + void FileOpenNotify(int32_t pp_error); + + Plugin* instance_; + nacl::string url_to_open_; + nacl::string url_; + pp::CompletionCallback file_open_notify_callback_; + pp::FileIO file_reader_; + const PPB_FileIOTrusted* file_io_trusted_interface_; + pp::URLLoader url_loader_; + pp::CompletionCallbackFactory<FileDownloader> callback_factory_; + int64_t open_time_; + DownloadFlags flags_; + static const uint32_t kTempBufferSize = 1024; + char temp_buffer_[kTempBufferSize]; + std::deque<char> buffer_; + UrlSchemeType url_scheme_; +}; +} // namespace plugin; +#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_FILE_DOWNLOADER_H_ diff --git a/ppapi/native_client/src/trusted/plugin/manifest.cc b/ppapi/native_client/src/trusted/plugin/manifest.cc new file mode 100644 index 0000000..ca452f8 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/manifest.cc @@ -0,0 +1,506 @@ +/* + * 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 <algorithm> + +#include "native_client/src/trusted/plugin/manifest.h" + +#include <stdlib.h> + +#include "native_client/src/include/nacl_base.h" +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/nacl_string.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/src/trusted/plugin/plugin_error.h" +#include "native_client/src/trusted/plugin/utility.h" +#include "native_client/src/third_party_mod/jsoncpp/include/json/reader.h" +#include "ppapi/cpp/dev/url_util_dev.h" +#include "ppapi/cpp/var.h" + +namespace plugin { + +namespace { +// Top-level section name keys +const char* const kProgramKey = "program"; +const char* const kInterpreterKey = "interpreter"; +const char* const kFilesKey = "files"; + +// ISA Dictionary keys +const char* const kX8632Key = "x86-32"; +const char* const kX8664Key = "x86-64"; +const char* const kArmKey = "arm"; +const char* const kPortableKey = "portable"; +const char* const kUrlKey = "url"; + +// Sample manifest file: +// { +// "program": { +// "x86-32": {"url": "myprogram_x86-32.nexe"}, +// "x86-64": {"url": "myprogram_x86-64.nexe"}, +// "arm": {"url": "myprogram_arm.nexe"}, +// "portable": {"url": "myprogram.pexe"} +// }, +// "interpreter": { +// "x86-32": {"url": "interpreter_x86-32.nexe"}, +// "x86-64": {"url": "interpreter_x86-64.nexe"}, +// "arm": {"url": "interpreter_arm.nexe"} +// }, +// "files": { +// "foo.txt": { +// "portable": {"url": "foo.txt"} +// }, +// "bar.txt": { +// "x86-32": {"url": "x86-32/bar.txt"}, +// "portable": {"url": "bar.txt"} +// } +// } +// } + +// TODO(jvoung): Remove these when we find a better way to store/install them. +const char* const kPnaclLlcKey = "pnacl-llc"; +const char* const kPnaclLdKey = "pnacl-ld"; + +// Looks up |property_name| in the vector |valid_names| with length +// |valid_name_count|. Returns true if |property_name| is found. +bool FindMatchingProperty(nacl::string property_name, + const char** valid_names, + size_t valid_name_count) { + for (size_t i = 0; i < valid_name_count; ++i) { + if (property_name == valid_names[i]) { + return true; + } + } + return false; +} + +// Validates that |dictionary| is a valid ISA dictionary. An ISA dictionary +// is validated to have keys from within the set of recognized ISAs. Unknown +// ISAs are allowed, but ignored and warnings are produced. It is also validated +// that it must have an entry to match the ISA specified in |sandbox_isa| or +// have a fallback 'portable' entry if there is no match. Returns true if +// |dictionary| is an ISA to URL map. Sets |error_string| to something +// descriptive if it fails. +bool IsValidISADictionary(const Json::Value& dictionary, + const nacl::string& sandbox_isa, + nacl::string* error_string) { + if (error_string == NULL) + return false; + + // An ISA to URL dictionary has to be an object. + if (!dictionary.isObject()) { + *error_string = " property is not an ISA to URL dictionary"; + return false; + } + // The keys to the dictionary have to be valid ISA names. + Json::Value::Members members = dictionary.getMemberNames(); + for (size_t i = 0; i < members.size(); ++i) { + // The known ISA values for ISA dictionaries in the manifest. + static const char* kManifestISAProperties[] = { + kX8632Key, + kX8664Key, + kArmKey, + kPortableKey + }; + nacl::string property_name = members[i]; + if (!FindMatchingProperty(property_name, + kManifestISAProperties, + NACL_ARRAY_SIZE(kManifestISAProperties))) { + PLUGIN_PRINTF(("IsValidISADictionary: unrecognized ISA '%s'.\n", + property_name.c_str())); + } + Json::Value url_spec = dictionary[property_name]; + if (!url_spec.isObject()) { + *error_string = " ISA property '" + property_name + + "' has non-dictionary value'" + url_spec.toStyledString() + "'."; + return false; + } + // Check properties of the arch-specific 'URL spec' dictionary + static const char* kManifestUrlSpecProperties[] = { + kUrlKey + }; + Json::Value::Members ISA_members = url_spec.getMemberNames(); + for (size_t j = 0; j < ISA_members.size(); ++j) { + nacl::string ISA_property_name = ISA_members[j]; + if (!FindMatchingProperty(ISA_property_name, + kManifestUrlSpecProperties, + NACL_ARRAY_SIZE(kManifestUrlSpecProperties))) { + PLUGIN_PRINTF(("IsValidISADictionary: unrecognized property for '%s'" + ": '%s'.", + property_name.c_str(), ISA_property_name.c_str())); + } + } + // A "url" key is required for each URL spec. + if (!url_spec.isMember(kUrlKey)) { + *error_string = " ISA property '" + property_name + + "' has no key '" + kUrlKey + "'."; + return false; + } + Json::Value url = url_spec[kUrlKey]; + if (!url.isString()) { + *error_string = " ISA property '" + property_name + + "' has non-string value '" + url.toStyledString() + + "' for key '" + kUrlKey + "'."; + return false; + } + } + + // TODO(elijahtaylor) add ISA resolver here if we expand ISAs to include + // micro-architectures that can resolve to multiple valid sandboxes. + bool has_isa = dictionary.isMember(sandbox_isa); + bool has_portable = dictionary.isMember(kPortableKey); + + if (!has_isa && !has_portable) { + *error_string = + " no version given for current arch and no portable version found."; + return false; + } + + return true; +} + +bool GetURLFromISADictionary(const Json::Value& dictionary, + const nacl::string& sandbox_isa, + nacl::string* url, + nacl::string* error_string, + bool* is_portable) { + if (url == NULL || error_string == NULL || is_portable == NULL) + return false; + + if (!IsValidISADictionary(dictionary, sandbox_isa, error_string)) + return false; + + const char* isa_string; + // The call to IsValidISADictionary() above guarantees that either + // sandbox_isa or kPortableKey is present in the dictionary. + bool has_portable = dictionary.isMember(kPortableKey); + bool has_isa = dictionary.isMember(sandbox_isa); + if ((has_portable && Manifest::PreferPortable()) || !has_isa) { + *is_portable = true; + isa_string = kPortableKey; + } else { + *is_portable = false; + isa_string = sandbox_isa.c_str(); + } + + const Json::Value& json_url = dictionary[isa_string][kUrlKey]; + *url = json_url.asString(); + + return true; +} + +// this will probably be replaced by jvoung's version that exposes +// is_portable checks +bool GetKeyUrl(const Json::Value& dictionary, + const nacl::string& key, + const nacl::string& sandbox_isa, + nacl::string* full_url, + nacl::string* error_string, + bool* is_portable) { + CHECK(full_url != NULL && error_string != NULL); + if (!dictionary.isMember(key)) { + *error_string = "file key not found in manifest"; + return false; + } + const Json::Value& isa_dict = dictionary[key]; + if (isa_dict.isMember(sandbox_isa)) { + *full_url = isa_dict[sandbox_isa][kUrlKey].asString(); + *is_portable = false; + return true; + } + if (isa_dict.isMember(kPortableKey)) { + *full_url = isa_dict[kPortableKey][kUrlKey].asString(); + *is_portable = true; + return true; + } + *error_string = "neither ISA-specific nor portable representations exist"; + return false; +} + +} // namespace + +bool Manifest::PreferPortable() { + return getenv("NACL_PREFER_PORTABLE_IN_MANIFEST") != NULL; +} + +bool Manifest::Init(const nacl::string& manifest_json, ErrorInfo* error_info) { + if (error_info == NULL) { + return false; + } + Json::Reader reader; + if (!reader.parse(manifest_json, dictionary_)) { + std::string json_error = reader.getFormatedErrorMessages(); + error_info->SetReport(ERROR_MANIFEST_PARSING, + "manifest JSON parsing failed: " + json_error); + return false; + } + // Parse has ensured the string was valid JSON. Check that it matches the + // manifest schema. + return MatchesSchema(error_info); +} + +bool Manifest::MatchesSchema(ErrorInfo* error_info) { + pp::Var exception; + if (error_info == NULL) { + return false; + } + if (!dictionary_.isObject()) { + error_info->SetReport( + ERROR_MANIFEST_SCHEMA_VALIDATE, + "manifest: is not a json dictionary."); + return false; + } + Json::Value::Members members = dictionary_.getMemberNames(); + for (size_t i = 0; i < members.size(); ++i) { + // The top level dictionary entries valid in the manifest file. + static const char* kManifestTopLevelProperties[] = { kProgramKey, + kInterpreterKey, + kFilesKey }; + nacl::string property_name = members[i]; + if (!FindMatchingProperty(property_name, + kManifestTopLevelProperties, + NACL_ARRAY_SIZE(kManifestTopLevelProperties))) { + PLUGIN_PRINTF(("Manifest::MatchesSchema: WARNING: unknown top-level " + "section '%s' in manifest.\n", property_name.c_str())); + } + } + + nacl::string error_string; + + // A manifest file must have a program section. + if (!dictionary_.isMember(kProgramKey)) { + error_info->SetReport( + ERROR_MANIFEST_SCHEMA_VALIDATE, + nacl::string("manifest: missing '") + kProgramKey + "' section."); + return false; + } + + // Validate the program section. + if (!IsValidISADictionary(dictionary_[kProgramKey], + sandbox_isa_, + &error_string)) { + error_info->SetReport( + ERROR_MANIFEST_SCHEMA_VALIDATE, + nacl::string("manifest: ") + kProgramKey + error_string); + return false; + } + + // Validate the interpreter section (if given). + if (dictionary_.isMember(kInterpreterKey)) { + if (!IsValidISADictionary(dictionary_[kProgramKey], + sandbox_isa_, + &error_string)) { + error_info->SetReport( + ERROR_MANIFEST_SCHEMA_VALIDATE, + nacl::string("manifest: ") + kInterpreterKey + error_string); + return false; + } + } + + // Validate the file dictionary (if given). + if (dictionary_.isMember(kFilesKey)) { + const Json::Value& files = dictionary_[kFilesKey]; + if (!files.isObject()) { + error_info->SetReport( + ERROR_MANIFEST_SCHEMA_VALIDATE, + nacl::string("manifest: '") + kFilesKey + "' is not a dictionary."); + } + Json::Value::Members members = files.getMemberNames(); + for (size_t i = 0; i < members.size(); ++i) { + nacl::string property_name = members[i]; + if (!IsValidISADictionary(files[property_name], + sandbox_isa_, + &error_string)) { + error_info->SetReport( + ERROR_MANIFEST_SCHEMA_VALIDATE, + nacl::string("manifest: file '") + property_name + "'" + + error_string); + return false; + } + } + } + + return true; +} + +bool Manifest::ResolveURL(const nacl::string& relative_url, + nacl::string* full_url, + ErrorInfo* error_info) const { + // The contents of the manifest are resolved relative to the manifest URL. + CHECK(url_util_ != NULL); + pp::Var resolved_url = + url_util_->ResolveRelativeToURL(pp::Var(manifest_base_url_), + relative_url); + if (!resolved_url.is_string()) { + error_info->SetReport( + ERROR_MANIFEST_RESOLVE_URL, + "could not resolve url '" + relative_url + + "' relative to manifest base url '" + manifest_base_url_.c_str() + + "'."); + return false; + } + *full_url = resolved_url.AsString(); + return true; +} + +bool Manifest::GetProgramURL(nacl::string* full_url, + ErrorInfo* error_info, + bool* is_portable) { + if (full_url == NULL || error_info == NULL || is_portable == NULL) + return false; + + Json::Value program = dictionary_[kProgramKey]; + + nacl::string nexe_url; + nacl::string error_string; + + if (!GetURLFromISADictionary(program, + sandbox_isa_, + &nexe_url, + &error_string, + is_portable)) { + error_info->SetReport(ERROR_MANIFEST_GET_NEXE_URL, + nacl::string("program:") + sandbox_isa_ + + error_string); + return false; + } + + return ResolveURL(nexe_url, full_url, error_info); +} + +bool Manifest::GetFileKeys(std::set<nacl::string>* keys) const { + if (!dictionary_.isMember(kFilesKey)) { + // trivial success: no keys when there is no "files" section. + return true; + } + const Json::Value& files = dictionary_[kFilesKey]; + CHECK(files.isObject()); + Json::Value::Members members = files.getMemberNames(); + for (size_t i = 0; i < members.size(); ++i) { + keys->insert(members[i]); + } + return true; +} + +bool Manifest::ResolveKey(const nacl::string& key, + nacl::string* full_url, + ErrorInfo* error_info, + bool* is_portable) const { + NaClLog(3, "Manifest::ResolveKey(%s)\n", key.c_str()); + // key must be one of kProgramKey or kFileKey '/' file-section-key + + *full_url = ""; + if (key == kProgramKey) { + nacl::string error_string; + if (!GetKeyUrl(dictionary_, key, sandbox_isa_, + full_url, &error_string, is_portable)) { + error_info->SetReport(ERROR_MANIFEST_RESOLVE_URL, error_string); + return false; + } + return true; + } + nacl::string::const_iterator p = find(key.begin(), key.end(), '/'); + if (p == key.end()) { + error_info->SetReport(ERROR_MANIFEST_RESOLVE_URL, + nacl::string("ResolveKey: invalid key, no slash: ") + + key); + return false; + } + + // generalize to permit other sections? + nacl::string prefix(key.begin(), p); + if (prefix != kFilesKey) { + error_info->SetReport(ERROR_MANIFEST_RESOLVE_URL, + nacl::string("ResolveKey: invalid key: not \"files\"" + " prefix: ") + key); + return false; + } + + nacl::string rest(p + 1, key.end()); + + const Json::Value& files = dictionary_[kFilesKey]; + CHECK(files.isObject()); + if (!files.isMember(rest)) { + error_info->SetReport( + ERROR_MANIFEST_RESOLVE_URL, + nacl::string("ResolveKey: no such \"files\" entry: ") + key); + *is_portable = false; + return false; + } + nacl::string error_string; + if (!GetKeyUrl(files, rest, sandbox_isa_, + full_url, &error_string, is_portable)) { + error_info->SetReport(ERROR_MANIFEST_RESOLVE_URL, error_string); + *full_url = ""; + return false; + } + return true; +} + +// TODO(jvoung): We won't need these if we figure out how to install llc and ld. +bool Manifest::GetLLCURL(nacl::string* full_url, ErrorInfo* error_info) { + if (full_url == NULL || error_info == NULL) + return false; + + Json::Value pnacl_llc = dictionary_[kPnaclLlcKey]; + + nacl::string nexe_url; + nacl::string error_string; + bool is_portable; + if (!GetURLFromISADictionary(pnacl_llc, + sandbox_isa_, + &nexe_url, + &error_string, + &is_portable)) { + error_info->SetReport(ERROR_MANIFEST_GET_NEXE_URL, + nacl::string(kPnaclLlcKey) + ":" + sandbox_isa_ + + error_string); + return false; + } + + if (is_portable) { + // Bootstrap problem -- we need this to translate portable programs! + error_info->SetReport(ERROR_MANIFEST_GET_NEXE_URL, + nacl::string(kPnaclLlcKey) + + " must be pre-translated for " + sandbox_isa_ + "!"); + return false; + } + + return ResolveURL(nexe_url, full_url, error_info); +} + +bool Manifest::GetLDURL(nacl::string* full_url, ErrorInfo* error_info) { + if (full_url == NULL || error_info == NULL) + return false; + + Json::Value pnacl_ld = dictionary_[kPnaclLdKey]; + + nacl::string nexe_url; + nacl::string error_string; + bool is_portable; + if (!GetURLFromISADictionary(pnacl_ld, + sandbox_isa_, + &nexe_url, + &error_string, + &is_portable)) { + error_info->SetReport(ERROR_MANIFEST_GET_NEXE_URL, + nacl::string(kPnaclLdKey) + ":" + sandbox_isa_ + + error_string); + return false; + } + + if (is_portable) { + // Bootstrap problem -- we need this to translate portable programs! + error_info->SetReport(ERROR_MANIFEST_GET_NEXE_URL, + nacl::string(kPnaclLdKey) + + " must be pre-translated for " + sandbox_isa_ + "!"); + return false; + } + + return ResolveURL(nexe_url, full_url, error_info); +} + +} // namespace plugin diff --git a/ppapi/native_client/src/trusted/plugin/manifest.h b/ppapi/native_client/src/trusted/plugin/manifest.h new file mode 100644 index 0000000..cc3e3e2 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/manifest.h @@ -0,0 +1,102 @@ +/* + * 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. + */ + +// Manifest file processing class. + +#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_MANIFEST_H_ +#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_MANIFEST_H_ + +#include <map> +#include <set> +#include <string> + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/nacl_string.h" +#include "native_client/src/third_party_mod/jsoncpp/include/json/value.h" + +namespace pp { +class URLUtil_Dev; +} // namespace pp + +namespace plugin { + +class ErrorInfo; + +class Manifest { + public: + Manifest(const pp::URLUtil_Dev* url_util, + const nacl::string& manifest_base_url, + const nacl::string& sandbox_isa) + : url_util_(url_util), + manifest_base_url_(manifest_base_url), + sandbox_isa_(sandbox_isa), + dictionary_(Json::nullValue) { } + ~Manifest() { } + + // Determines whether portable programs are chosen in manifest files over + // native programs. Normally the native version is selected if available. + static bool PreferPortable(); + + // Initialize the manifest object for use by later lookups. The return + // value is true if the manifest parses correctly and matches the schema. + bool Init(const nacl::string& json, ErrorInfo* error_info); + + // Gets the full program URL for the current sandbox ISA from the + // manifest file. Sets |is_portable| to |true| if the program is + // portable bitcode. + bool GetProgramURL(nacl::string* full_url, + ErrorInfo* error_info, + bool* is_portable); + + // TODO(jvoung): Get rid of these when we find a better way to + // store / install these. + // Gets the full nexe URL for the LLC nexe from the manifest file. + bool GetLLCURL(nacl::string* full_url, ErrorInfo* error_info); + + // Gets the full nexe URL for the LD nexe from the manifest file. + bool GetLDURL(nacl::string* full_url, ErrorInfo* error_info); + // end TODO(jvoung) + + // Resolves a URL relative to the manifest base URL + bool ResolveURL(const nacl::string& relative_url, + nacl::string* full_url, + ErrorInfo* error_info) const; + + // Gets the file names from the "files" section of the manifest. No + // checking that the keys' values are proper ISA dictionaries -- it + // is assumed that other consistency checks take care of that, and + // that the keys are appropriate for use with ResolveKey. + bool GetFileKeys(std::set<nacl::string>* keys) const; + + // Resolves a key from the "files" section to a fully resolved URL, + // i.e., relative URL values are fully expanded relative to the + // manifest's URL (via ResolveURL). If there was an error, details + // are reported via error_info, and is_portable, if non-NULL, tells + // the caller whether the resolution used the portable + // representation or an ISA-specific version of the file. + bool ResolveKey(const nacl::string& key, + nacl::string* full_url, + ErrorInfo* error_info, + bool* is_portable) const; + + private: + const pp::URLUtil_Dev* url_util_; + nacl::string manifest_base_url_; + nacl::string sandbox_isa_; + Json::Value dictionary_; + + // Checks that |dictionary_| is a valid manifest, according to the schema. + // Returns true on success, and sets |error_info| to a detailed message + // if not. + bool MatchesSchema(ErrorInfo* error_info); + + NACL_DISALLOW_COPY_AND_ASSIGN(Manifest); +}; + + +} // namespace plugin + +#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_MANIFEST_H_ diff --git a/ppapi/native_client/src/trusted/plugin/method_map.cc b/ppapi/native_client/src/trusted/plugin/method_map.cc new file mode 100644 index 0000000..7ac5cae --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/method_map.cc @@ -0,0 +1,210 @@ +/* + * Copyright 2008 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 <map> + +#include "native_client/src/include/checked_cast.h" +#include "native_client/src/shared/platform/nacl_exit.h" +#include "native_client/src/shared/platform/nacl_log.h" +#include "native_client/src/trusted/desc/nacl_desc_base.h" +#include "native_client/src/trusted/nonnacl_util/sel_ldr_launcher.h" +#include "native_client/src/trusted/plugin/method_map.h" +#include "native_client/src/trusted/plugin/plugin.h" +#include "native_client/src/trusted/plugin/srpc_client.h" +#include "native_client/src/trusted/plugin/utility.h" + +using nacl::assert_cast; + +namespace { + +uint32_t ArgsLength(NaClSrpcArg** index) { + uint32_t i; + for (i = 0; (i < NACL_SRPC_MAX_ARGS) && NULL != index[i]; ++i) { + // Empty body. Avoids warning. + } + return i; +} + +} // namespace + +namespace plugin { + +bool SrpcParams::Init(const char* in_types, const char* out_types) { + if (!FillVec(ins_, in_types)) { + return false; + } + if (!FillVec(outs_, out_types)) { + FreeArguments(ins_); + return false; + } + return true; +} + +uint32_t SrpcParams::InputLength() const { + return ArgsLength(const_cast<NaClSrpcArg**>(ins_)); +} + +uint32_t SrpcParams::OutputLength() const { + return ArgsLength(const_cast<NaClSrpcArg**>(outs_)); +} + +uint32_t SrpcParams::SignatureLength() const { + uint32_t in_length = ArgsLength(const_cast<NaClSrpcArg**>(ins_)); + uint32_t out_length = ArgsLength(const_cast<NaClSrpcArg**>(outs_)); + uint32_t array_outs = 0; + + for (uint32_t i = 0; i < out_length; ++i) { + switch (outs_[i]->tag) { + case NACL_SRPC_ARG_TYPE_CHAR_ARRAY: + case NACL_SRPC_ARG_TYPE_DOUBLE_ARRAY: + case NACL_SRPC_ARG_TYPE_INT_ARRAY: + case NACL_SRPC_ARG_TYPE_LONG_ARRAY: + ++array_outs; + break; + case NACL_SRPC_ARG_TYPE_STRING: + case NACL_SRPC_ARG_TYPE_BOOL: + case NACL_SRPC_ARG_TYPE_DOUBLE: + case NACL_SRPC_ARG_TYPE_INT: + case NACL_SRPC_ARG_TYPE_LONG: + case NACL_SRPC_ARG_TYPE_HANDLE: + case NACL_SRPC_ARG_TYPE_INVALID: + case NACL_SRPC_ARG_TYPE_OBJECT: + case NACL_SRPC_ARG_TYPE_VARIANT_ARRAY: + default: + break; + } + } + return in_length + array_outs; +} + +void SrpcParams::FreeAll() { + FreeArguments(ins_); + FreeArguments(outs_); + memset(ins_, 0, sizeof(ins_)); + memset(outs_, 0, sizeof(outs_)); +} + +bool SrpcParams::FillVec(NaClSrpcArg* vec[], const char* types) { + const size_t kLength = strlen(types); + if (kLength > NACL_SRPC_MAX_ARGS) { + return false; + } + // We use malloc/new here rather than new/delete, because the SRPC layer + // is written in C and hence will use malloc/free. + // This array will get deallocated by FreeArguments(). + if (kLength > 0) { + NaClSrpcArg* args = + reinterpret_cast<NaClSrpcArg*>(malloc(kLength * sizeof(*args))); + if (NULL == args) { + return false; + } + + memset(static_cast<void*>(args), 0, kLength * sizeof(*args)); + for (size_t i = 0; i < kLength; ++i) { + vec[i] = &args[i]; + args[i].tag = static_cast<NaClSrpcArgType>(types[i]); + } + } + vec[kLength] = NULL; + return true; +} + +void SrpcParams::FreeArguments(NaClSrpcArg* vec[]) { + if (NULL == vec[0]) { + return; + } + for (NaClSrpcArg** argp = vec; *argp; ++argp) { + FreeSrpcArg(*argp); + } + // Free the vector containing the arguments themselves that was + // allocated with FillVec(). + free(vec[0]); +} + +MethodInfo::~MethodInfo() { + free(reinterpret_cast<void*>(name_)); + free(reinterpret_cast<void*>(ins_)); + free(reinterpret_cast<void*>(outs_)); + } + +bool InitSrpcArgArray(NaClSrpcArg* arr, int size) { + arr->tag = NACL_SRPC_ARG_TYPE_VARIANT_ARRAY; + arr->arrays.varr = reinterpret_cast<NaClSrpcArg*>( + calloc(size, sizeof(*(arr->arrays.varr)))); + if (NULL == arr->arrays.varr) { + arr->u.count = 0; + return false; + } + arr->u.count = size; + return true; +} + +void FreeSrpcArg(NaClSrpcArg* arg) { + switch (arg->tag) { + case NACL_SRPC_ARG_TYPE_CHAR_ARRAY: + free(arg->arrays.carr); + break; + case NACL_SRPC_ARG_TYPE_DOUBLE_ARRAY: + free(arg->arrays.darr); + break; + case NACL_SRPC_ARG_TYPE_HANDLE: + break; + case NACL_SRPC_ARG_TYPE_INT_ARRAY: + free(arg->arrays.iarr); + break; + case NACL_SRPC_ARG_TYPE_LONG_ARRAY: + free(arg->arrays.larr); + break; + case NACL_SRPC_ARG_TYPE_STRING: + // All strings that are passed in SrpcArg must be allocated using + // malloc! We cannot use browser's allocation API + // since some of SRPC arguments is handled outside of the plugin code. + free(arg->arrays.str); + break; + case NACL_SRPC_ARG_TYPE_VARIANT_ARRAY: + if (arg->arrays.varr) { + for (uint32_t i = 0; i < arg->u.count; i++) { + FreeSrpcArg(&arg->arrays.varr[i]); + } + } + break; + case NACL_SRPC_ARG_TYPE_OBJECT: + // This is a pointer to a scriptable object and should be released + // by the browser + break; + case NACL_SRPC_ARG_TYPE_BOOL: + case NACL_SRPC_ARG_TYPE_DOUBLE: + case NACL_SRPC_ARG_TYPE_INT: + case NACL_SRPC_ARG_TYPE_LONG: + case NACL_SRPC_ARG_TYPE_INVALID: + default: + break; + } +} + +MethodMap::~MethodMap() { + MethodMapStorage::iterator it; + while ((it = method_map_.begin()) != method_map_.end()) { + delete(it->second); + method_map_.erase(it); + } +} + +MethodInfo* MethodMap::GetMethod(uintptr_t method_id) { + return method_map_[method_id]; +} + +void MethodMap::AddMethod(uintptr_t method_id, MethodInfo *info) { + if (method_map_.find(method_id) != method_map_.end()) { + // the method already exists + NaClAbort(); + } + method_map_[method_id] = info; + method_map_keys_.push_back(method_id); +} + +} // namespace plugin diff --git a/ppapi/native_client/src/trusted/plugin/method_map.h b/ppapi/native_client/src/trusted/plugin/method_map.h new file mode 100644 index 0000000..05037f9 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/method_map.h @@ -0,0 +1,127 @@ +/* + * Copyright 2008 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. + */ + +// Lookup table types for method dispatching. + +#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_METHOD_MAP_H +#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_METHOD_MAP_H + +#include <limits.h> +#include <map> +#include <vector> + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/portability_string.h" +#include "native_client/src/shared/srpc/nacl_srpc.h" + +namespace plugin { + +class Plugin; + +bool InitSrpcArgArray(NaClSrpcArg* arr, int size); +void FreeSrpcArg(NaClSrpcArg* arg); + +// A utility class that builds and deletes parameter vectors used in rpcs. +class SrpcParams { + public: + SrpcParams() : exception_string_(NULL) { + memset(ins_, 0, sizeof(ins_)); + memset(outs_, 0, sizeof(outs_)); + } + + SrpcParams(const char* in_types, const char* out_types) + : exception_string_(NULL) { + if (!Init(in_types, out_types)) { + FreeAll(); + } + } + + ~SrpcParams() { + FreeAll(); + free(exception_string_); + } + + bool Init(const char* in_types, const char* out_types); + uint32_t SignatureLength() const; + uint32_t InputLength() const; + uint32_t OutputLength() const; + + NaClSrpcArg** ins() const { return const_cast<NaClSrpcArg**>(ins_); } + NaClSrpcArg** outs() const { return const_cast<NaClSrpcArg**>(outs_); } + + char* exception_string() const { return exception_string_; } + void set_exception_string(const char* msg) { + exception_string_ = STRDUP(msg); + } + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(SrpcParams); + void FreeAll(); + bool FillVec(NaClSrpcArg* vec[], const char* types); + void FreeArguments(NaClSrpcArg* vec[]); + // The ins_ and outs_ arrays contain one more element, to hold a NULL pointer + // to indicate the end of the list. + NaClSrpcArg* ins_[NACL_SRPC_MAX_ARGS + 1]; + NaClSrpcArg* outs_[NACL_SRPC_MAX_ARGS + 1]; + char* exception_string_; +}; + +typedef bool (*RpcFunction)(void* obj, SrpcParams* params); + +// MethodInfo records the method names and type signatures of an SRPC server. +class MethodInfo { + public: + // statically defined method - called through a pointer + MethodInfo(const RpcFunction function_ptr, + const char* name, + const char* ins, + const char* outs, + // index is set to UINT_MAX for methods implemented by the plugin, + // All methods implemented by nacl modules have indexes + // that are lower than UINT_MAX. + const uint32_t index = UINT_MAX) : + function_ptr_(function_ptr), + name_(STRDUP(name)), + ins_(STRDUP(ins)), + outs_(STRDUP(outs)), + index_(index) { } + ~MethodInfo(); + + RpcFunction function_ptr() const { return function_ptr_; } + char* name() const { return name_; } + char* ins() const { return ins_; } + char* outs() const { return outs_; } + uint32_t index() const { return index_; } + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(MethodInfo); + RpcFunction function_ptr_; + char* name_; + char* ins_; + char* outs_; + uint32_t index_; +}; + +class MethodMap { + public: + MethodMap() {} + ~MethodMap(); + MethodInfo* GetMethod(uintptr_t method_id); + void AddMethod(uintptr_t method_id, MethodInfo* info); + + typedef std::vector<uintptr_t> MethodMapKeys; + MethodMapKeys* Keys() { return &method_map_keys_; } + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(MethodMap); + typedef std::map<uintptr_t, MethodInfo*> MethodMapStorage; + MethodMapStorage method_map_; + MethodMapKeys method_map_keys_; +}; + +} // namespace plugin + +#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_METHOD_MAP_H diff --git a/ppapi/native_client/src/trusted/plugin/module_ppapi.cc b/ppapi/native_client/src/trusted/plugin/module_ppapi.cc new file mode 100644 index 0000000..a537bc8 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/module_ppapi.cc @@ -0,0 +1,84 @@ +/* + * 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/platform/nacl_time.h" +#include "native_client/src/trusted/desc/nrd_all_modules.h" +#include "native_client/src/trusted/handle_pass/browser_handle.h" +#include "native_client/src/trusted/plugin/nacl_entry_points.h" +#include "native_client/src/trusted/plugin/plugin.h" + +#include "ppapi/c/private/ppb_nacl_private.h" +#include "ppapi/cpp/module.h" + +GetURandomFDFunc get_urandom_fd; + +namespace plugin { + +class ModulePpapi : public pp::Module { + public: + ModulePpapi() : pp::Module(), init_was_successful_(false) { + PLUGIN_PRINTF(("ModulePpapi::ModulePpapi (this=%p)\n", + static_cast<void*>(this))); + } + + virtual ~ModulePpapi() { + if (init_was_successful_) { + NaClNrdAllModulesFini(); + } + PLUGIN_PRINTF(("ModulePpapi::~ModulePpapi (this=%p)\n", + static_cast<void*>(this))); + } + + virtual bool Init() { + // Ask the browser for an interface which provides missing functions + const PPB_NaCl_Private* ptr = reinterpret_cast<const PPB_NaCl_Private*>( + GetBrowserInterface(PPB_NACL_PRIVATE_INTERFACE)); + + if (NULL == ptr) { + PLUGIN_PRINTF(("ModulePpapi::Init failed: " + "GetBrowserInterface returned NULL\n")); + return false; + } + + launch_nacl_process = reinterpret_cast<LaunchNaClProcessFunc>( + ptr->LaunchSelLdr); + get_urandom_fd = ptr->UrandomFD; + + // In the plugin, we don't need high resolution time of day. + NaClAllowLowResolutionTimeOfDay(); + NaClNrdAllModulesInit(); + +#if NACL_WINDOWS && !defined(NACL_STANDALONE) + NaClHandlePassBrowserInit(); +#endif + init_was_successful_ = true; + return true; + } + + virtual pp::Instance* CreateInstance(PP_Instance pp_instance) { + PLUGIN_PRINTF(("ModulePpapi::CreateInstance (pp_instance=%"NACL_PRId32")\n", + pp_instance)); + Plugin* plugin = Plugin::New(pp_instance); + PLUGIN_PRINTF(("ModulePpapi::CreateInstance (return %p)\n", + static_cast<void* >(plugin))); + return plugin; + } + + private: + bool init_was_successful_; +}; + +} // namespace plugin + + +namespace pp { + +Module* CreateModule() { + PLUGIN_PRINTF(("CreateModule ()\n")); + return new plugin::ModulePpapi(); +} + +} // namespace pp diff --git a/ppapi/native_client/src/trusted/plugin/nacl_entry_points.h b/ppapi/native_client/src/trusted/plugin/nacl_entry_points.h new file mode 100644 index 0000000..ff00259 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/nacl_entry_points.h @@ -0,0 +1,63 @@ +/* +* Copyright 2009, Google Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are +* met: +* +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above +* copyright notice, this list of conditions and the following disclaimer +* in the documentation and/or other materials provided with the +* distribution. +* * Neither the name of Google Inc. nor the names of its +* contributors may be used to endorse or promote products derived from +* this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_NACL_ENTRY_POINTS_H_ +#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_NACL_ENTRY_POINTS_H_ + +#include <stddef.h> + +#include <map> +#include <string> + +#include "native_client/src/shared/imc/nacl_imc.h" + + +typedef bool (*LaunchNaClProcessFunc)(const char* url, + int socket_count, + nacl::Handle* result_sockets, + nacl::Handle* nacl_process_handle, + int* nacl_process_id); + +typedef int (*GetURandomFDFunc)(void); + + +extern LaunchNaClProcessFunc launch_nacl_process; +extern GetURandomFDFunc get_urandom_fd; + +// Registers the internal NaCl plugin with PluginList. +// Old version. TODO(mseaborn): Remove this eventually, when Chromium +// has stopped using it for a while. Note that this is still called +// by Chromium in the browser process. +void RegisterInternalNaClPlugin(); +// New version. +void RegisterInternalNaClPlugin(const std::map<std::string, uintptr_t>& funcs); + +#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_NACL_ENTRY_POINTS_H_ diff --git a/ppapi/native_client/src/trusted/plugin/nacl_subprocess.cc b/ppapi/native_client/src/trusted/plugin/nacl_subprocess.cc new file mode 100644 index 0000000..c931a37 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/nacl_subprocess.cc @@ -0,0 +1,76 @@ +// 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/trusted/plugin/nacl_subprocess.h" + +#include "native_client/src/trusted/plugin/plugin_error.h" +#include "native_client/src/trusted/plugin/scriptable_handle.h" +#include "native_client/src/trusted/plugin/service_runtime.h" + +namespace plugin { + +nacl::string NaClSubprocess::description() const { + nacl::stringstream ss; + if (assigned_id_ == kMainSubprocessId) { + ss << "main subprocess"; + } else { + ss << "helper subprocess #" << assigned_id_; + } + return ss.str(); +} + +nacl::string NaClSubprocess::detailed_description() const { + nacl::stringstream ss; + ss << description() + << "={ this=" << static_cast<const void*>(this) + << ", srpc_client=" << static_cast<void*>(srpc_client_.get()) + << ", service_runtime=" << static_cast<void*>(service_runtime_.get()) + << " }"; + return ss.str(); +} + +// Shutdown the socket connection and service runtime, in that order. +void NaClSubprocess::Shutdown() { + srpc_client_.reset(NULL); + if (service_runtime_.get() != NULL) { + service_runtime_->Shutdown(); + service_runtime_.reset(NULL); + } +} + +NaClSubprocess::~NaClSubprocess() { + Shutdown(); +} + +bool NaClSubprocess::StartSrpcServices() { + srpc_client_.reset(service_runtime_->SetupAppChannel()); + return NULL != srpc_client_.get(); +} + +bool NaClSubprocess::StartJSObjectProxy(Plugin* plugin, ErrorInfo* error_info) { + return srpc_client_->StartJSObjectProxy(plugin, error_info); +} + +bool NaClSubprocess::HasMethod(uintptr_t method_id) const { + if (NULL == srpc_client_.get()) { + return false; + } + return srpc_client_->HasMethod(method_id); +} + +bool NaClSubprocess::InitParams(uintptr_t method_id, SrpcParams* params) const { + if (NULL == srpc_client_.get()) { + return false; + } + return srpc_client_->InitParams(method_id, params); +} + +bool NaClSubprocess::Invoke(uintptr_t method_id, SrpcParams* params) const { + if (NULL == srpc_client_.get()) { + return false; + } + return srpc_client_->Invoke(method_id, params); +} + +} // namespace plugin diff --git a/ppapi/native_client/src/trusted/plugin/nacl_subprocess.h b/ppapi/native_client/src/trusted/plugin/nacl_subprocess.h new file mode 100644 index 0000000..7a893d3 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/nacl_subprocess.h @@ -0,0 +1,82 @@ +// 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. + +// Instances of NaCl modules spun up within the plugin as a subprocess. +// This may represent the "main" nacl module, or it may represent helpers +// that perform various tasks within the plugin, for example, +// a NaCl module for a compiler could be loaded to translate LLVM bitcode +// into native code. + +#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_NACL_SUBPROCESS_H_ +#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_NACL_SUBPROCESS_H_ + +#include "native_client/src/include/nacl_string.h" +#include "native_client/src/trusted/plugin/service_runtime.h" +#include "native_client/src/trusted/plugin/srpc_client.h" + +namespace plugin { + +class Plugin; +class ServiceRuntime; + +// Identifier for helper NaCl nexes. Should be non-negative for valid nexes. +typedef int32_t NaClSubprocessId; +const NaClSubprocessId kInvalidNaClSubprocessId = -1; +const NaClSubprocessId kMainSubprocessId = -2; + +// A class representing an instance of a NaCl module, loaded by the plugin. +class NaClSubprocess { + public: + NaClSubprocess(NaClSubprocessId assigned_id, + ServiceRuntime* service_runtime, + SrpcClient* srpc_client) + : assigned_id_(assigned_id), + service_runtime_(service_runtime), + srpc_client_(srpc_client) { + } + virtual ~NaClSubprocess(); + + ServiceRuntime* service_runtime() const { return service_runtime_.get(); } + void set_service_runtime(ServiceRuntime* service_runtime) { + service_runtime_.reset(service_runtime); + } + + // The socket used for communicating w/ the NaCl module. + SrpcClient* srpc_client() const { return srpc_client_.get(); } + void set_socket(SrpcClient* srpc_client) { srpc_client_.reset(srpc_client); } + + // A basic description of the subprocess. + nacl::string description() const; + + // A detailed description of the subprocess that may contain addresses. + // Only use for debugging, but do not expose this to untrusted webapps. + nacl::string detailed_description() const; + + // Start up interfaces. + bool StartSrpcServices(); + bool StartJSObjectProxy(Plugin* plugin, ErrorInfo* error_info); + + // Interact. + bool HasMethod(uintptr_t method_id) const; + bool InitParams(uintptr_t method_id, SrpcParams* params) const; + bool Invoke(uintptr_t method_id, SrpcParams* params) const; + + // Fully shut down the subprocess. + void Shutdown(); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(NaClSubprocess); + + NaClSubprocessId assigned_id_; + + // The service runtime representing the NaCl module instance. + nacl::scoped_ptr<ServiceRuntime> service_runtime_; + + // Ownership of srpc_client taken from the service runtime. + nacl::scoped_ptr<SrpcClient> srpc_client_; +}; + +} // namespace plugin + +#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_NACL_SUBPROCESS_H_ diff --git a/ppapi/native_client/src/trusted/plugin/nexe_arch.cc b/ppapi/native_client/src/trusted/plugin/nexe_arch.cc new file mode 100644 index 0000000..0a5c7a4 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/nexe_arch.cc @@ -0,0 +1,12 @@ +// Copyright 2010 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/trusted/plugin/nexe_arch.h" + +#if defined(NACL_STANDALONE) +const char* NaClPluginGetSandboxISA() { + return plugin::GetSandboxISA(); +} +#endif + diff --git a/ppapi/native_client/src/trusted/plugin/nexe_arch.h b/ppapi/native_client/src/trusted/plugin/nexe_arch.h new file mode 100644 index 0000000..3fb24ea8 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/nexe_arch.h @@ -0,0 +1,41 @@ +/* + * Copyright 2010 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. + */ + +// Routines for determining the most appropriate NaCl executable for +// the current CPU's architecture. + +#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_NEXE_ARCH_H_ +#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_NEXE_ARCH_H_ + +#include "native_client/src/include/portability.h" + +namespace plugin { +// Returns the kind of SFI sandbox implemented by sel_ldr on this +// platform. See the implementation in nexe_arch.cc for possible values. +// +// This is a function of the current CPU, OS, browser, installed +// sel_ldr(s). It is not sufficient to derive the result only from +// build-time parameters since, for example, an x86-32 plugin is +// capable of launching a 64-bit NaCl sandbox if a 64-bit sel_ldr is +// installed (and indeed, may only be capable of launching a 64-bit +// sandbox). +// +// Note: The platform-sepcific implementations for this are under +// <platform>/nexe_arch.cc +const char* GetSandboxISA(); +} // namespace plugin + +#if defined(NACL_STANDALONE) +// These symbols are for linking with things like unit test frameworks that +// want to get at the C++ symbol names defined above in an un-mangled way. +// TODO(dspringer): Figure out how to link the shared libs with the test +// harness directly, and get rid of these wrappers. +EXTERN_C_BEGIN +DLLEXPORT const char* NaClPluginGetSandboxISA(); +EXTERN_C_END +#endif + +#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_NEXE_ARCH_H_ diff --git a/ppapi/native_client/src/trusted/plugin/osx_ppapi/Info.plist b/ppapi/native_client/src/trusted/plugin/osx_ppapi/Info.plist new file mode 100644 index 0000000..b066504 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/osx_ppapi/Info.plist @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>English</string> + <key>CFBundleExecutable</key> + <string>ppNaClPlugin</string> + <key>CFBundleIdentifier</key> + <string>com.google.ppNaClPlugin</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundlePackageType</key> + <string>BRPL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>nacl</string> + <key>CFBundleVersion</key> + <string>0.1</string> + <key>CFPlugInDynamicRegisterFunction</key> + <string></string> + <key>CFPlugInDynamicRegistration</key> + <string>NO</string> + <key>CFPlugInUnloadFunction</key> + <string></string> + <key>WebPluginDescription</key> + <string>ppNaClPlugin</string> + <key>NSPrincipalClass</key> + <string>ppNaClPlugin</string> + <key>WebPluginMIMETypes</key> + <dict> + <key>application/x-nacl</key> + <dict> + <key>WebPluginTypeDescription</key> + <string>PPAPI Native Client SimpleRPC interaction</string> + <key>WebPluginExtensions</key> + <array> + <string>nexe,nacl</string> + </array> + </dict> + </dict> + <key>WebPluginName</key> + <string>Google Native Client Plugin</string> +</dict> +</plist> diff --git a/ppapi/native_client/src/trusted/plugin/osx_ppapi/ppNaClPlugin.r b/ppapi/native_client/src/trusted/plugin/osx_ppapi/ppNaClPlugin.r new file mode 100644 index 0000000..af3f807 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/osx_ppapi/ppNaClPlugin.r @@ -0,0 +1,15 @@ +#include <CoreServices/CoreServices.r> + +resource 'STR#' (126) { { + "PPAPI NativeClient", + "PPAPI NativeClient Plug-in" +} }; + +resource 'STR#' (127) { { + "PPAPI NativeClient Module - SRPC", +} }; + +resource 'STR#' (128) { { + "application/x-nacl", + "nexe", +} }; diff --git a/ppapi/native_client/src/trusted/plugin/plugin.cc b/ppapi/native_client/src/trusted/plugin/plugin.cc new file mode 100644 index 0000000..6a3d5c8 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/plugin.cc @@ -0,0 +1,1869 @@ +/* + * 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. + */ + +#ifdef _MSC_VER +// Do not warn about use of std::copy with raw pointers. +#pragma warning(disable : 4996) +#endif + +#include "native_client/src/trusted/plugin/plugin.h" + +#include <assert.h> +#include <fcntl.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <sys/types.h> +#include <sys/stat.h> + +#include <algorithm> +#include <deque> +#include <string> +#include <vector> + +#include "native_client/src/include/nacl_base.h" +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/include/nacl_string.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/include/portability_io.h" +#include "native_client/src/include/portability_string.h" +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/src/shared/platform/nacl_time.h" +#include "native_client/src/shared/ppapi_proxy/browser_ppp.h" +#include "native_client/src/trusted/desc/nacl_desc_base.h" +#include "native_client/src/trusted/desc/nacl_desc_conn_cap.h" +#include "native_client/src/trusted/desc/nacl_desc_wrapper.h" +#include "native_client/src/trusted/handle_pass/browser_handle.h" +#include "native_client/src/trusted/nonnacl_util/sel_ldr_launcher.h" +#include "native_client/src/trusted/plugin/browser_interface.h" +#include "native_client/src/trusted/plugin/desc_based_handle.h" +#include "native_client/src/trusted/plugin/manifest.h" +#include "native_client/src/trusted/plugin/nacl_subprocess.h" +#include "native_client/src/trusted/plugin/nexe_arch.h" +#include "native_client/src/trusted/plugin/plugin_error.h" +#include "native_client/src/trusted/plugin/scriptable_handle.h" +#include "native_client/src/trusted/plugin/service_runtime.h" +#include "native_client/src/trusted/plugin/string_encoding.h" +#include "native_client/src/trusted/plugin/utility.h" +#include "native_client/src/trusted/service_runtime/include/sys/fcntl.h" +#include "native_client/src/trusted/service_runtime/nacl_error_code.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_input_event.h" +#include "ppapi/c/ppp_instance.h" +#include "ppapi/c/private/ppb_uma_private.h" +#include "ppapi/cpp/dev/find_dev.h" +#include "ppapi/cpp/dev/printing_dev.h" +#include "ppapi/cpp/dev/scrollbar_dev.h" +#include "ppapi/cpp/dev/selection_dev.h" +#include "ppapi/cpp/dev/url_util_dev.h" +#include "ppapi/cpp/dev/widget_client_dev.h" +#include "ppapi/cpp/dev/zoom_dev.h" +#include "ppapi/cpp/image_data.h" +#include "ppapi/cpp/input_event.h" +#include "ppapi/cpp/module.h" +#include "ppapi/cpp/rect.h" + +using ppapi_proxy::BrowserPpp; + +namespace plugin { + +namespace { + +bool GetReadyStateProperty(void* obj, SrpcParams* params) { + Plugin* plugin = static_cast<Plugin*>(obj); + params->outs()[0]->u.ival = plugin->nacl_ready_state(); + return true; +} + +const char* const kTypeAttribute = "type"; +// The "src" attribute of the <embed> tag. The value is expected to be either +// a URL or URI pointing to the manifest file (which is expected to contain +// JSON matching ISAs with .nexe URLs). +const char* const kSrcManifestAttribute = "src"; +// The "nacl" attribute of the <embed> tag. We use the value of this attribute +// to find the manifest file when NaCl is registered as a plug-in for another +// MIME type because the "src" attribute is used to supply us with the resource +// of that MIME type that we're supposed to display. +const char* const kNaClManifestAttribute = "nacl"; +// This is a pretty arbitrary limit on the byte size of the NaCl manfest file. +// Note that the resulting string object has to have at least one byte extra +// for the null termination character. +const size_t kNaClManifestMaxFileBytes = 1024 * 1024; + +// URL schemes that we treat in special ways. +const char* const kChromeExtensionUriScheme = "chrome-extension"; +const char* const kDataUriScheme = "data"; + +// The key used to find the dictionary nexe URLs in the manifest file. +const char* const kNexesKey = "nexes"; + +bool GetLastError(void* obj, SrpcParams* params) { + NaClSrpcArg** outs = params->outs(); + PLUGIN_PRINTF(("GetLastError (obj=%p)\n", obj)); + + Plugin* plugin = static_cast<Plugin*>(obj); + outs[0]->arrays.str = strdup(plugin->last_error_string().c_str()); + return true; +} + +// Up to 20 seconds +const int64_t kTimeSmallMin = 1; // in ms +const int64_t kTimeSmallMax = 20000; // in ms +const uint32_t kTimeSmallBuckets = 100; + +// Up to 3 minutes, 20 seconds +const int64_t kTimeMediumMin = 10; // in ms +const int64_t kTimeMediumMax = 200000; // in ms +const uint32_t kTimeMediumBuckets = 100; + +// Up to 33 minutes. +const int64_t kTimeLargeMin = 100; // in ms +const int64_t kTimeLargeMax = 2000000; // in ms +const uint32_t kTimeLargeBuckets = 100; + +const int64_t kSizeKBMin = 1; +const int64_t kSizeKBMax = 512*1024; // very large .nexe +const uint32_t kSizeKBBuckets = 100; + +const PPB_UMA_Private* GetUMAInterface() { + pp::Module *module = pp::Module::Get(); + CHECK(module); + return static_cast<const PPB_UMA_Private*>( + module->GetBrowserInterface(PPB_UMA_PRIVATE_INTERFACE)); +} + +void HistogramTimeSmall(const std::string& name, int64_t ms) { + if (ms < 0) return; + + const PPB_UMA_Private* ptr = GetUMAInterface(); + if (ptr == NULL) return; + + ptr->HistogramCustomTimes(pp::Var(name).pp_var(), + ms, + kTimeSmallMin, kTimeSmallMax, + kTimeSmallBuckets); +} + +void HistogramTimeMedium(const std::string& name, int64_t ms) { + if (ms < 0) return; + + const PPB_UMA_Private* ptr = GetUMAInterface(); + if (ptr == NULL) return; + + ptr->HistogramCustomTimes(pp::Var(name).pp_var(), + ms, + kTimeMediumMin, kTimeMediumMax, + kTimeMediumBuckets); +} + +void HistogramTimeLarge(const std::string& name, int64_t ms) { + if (ms < 0) return; + + const PPB_UMA_Private* ptr = GetUMAInterface(); + if (ptr == NULL) return; + + ptr->HistogramCustomTimes(pp::Var(name).pp_var(), + ms, + kTimeLargeMin, kTimeLargeMax, + kTimeLargeBuckets); +} + +void HistogramSizeKB(const std::string& name, int32_t sample) { + if (sample < 0) return; + + const PPB_UMA_Private* ptr = GetUMAInterface(); + if (ptr == NULL) return; + + ptr->HistogramCustomCounts(pp::Var(name).pp_var(), + sample, + kSizeKBMin, kSizeKBMax, + kSizeKBBuckets); +} + +void HistogramEnumerate(const std::string& name, int sample, int maximum, + int out_of_range_replacement) { + if (sample < 0 || sample >= maximum) { + if (out_of_range_replacement < 0) + // No replacement for bad input, abort. + return; + else + // Use a specific value to signal a bad input. + sample = out_of_range_replacement; + } + const PPB_UMA_Private* ptr = GetUMAInterface(); + if (ptr == NULL) return; + ptr->HistogramEnumeration(pp::Var(name).pp_var(), sample, maximum); +} + +void HistogramEnumerateOsArch(const std::string& sandbox_isa) { + enum NaClOSArch { + kNaClLinux32 = 0, + kNaClLinux64, + kNaClLinuxArm, + kNaClMac32, + kNaClMac64, + kNaClMacArm, + kNaClWin32, + kNaClWin64, + kNaClWinArm, + kNaClOSArchMax + }; + + NaClOSArch os_arch = kNaClOSArchMax; +#if NACL_LINUX + os_arch = kNaClLinux32; +#elif NACL_OSX + os_arch = kNaClMac32; +#elif NACL_WINDOWS + os_arch = kNaClWin32; +#endif + + if (sandbox_isa == "x86-64") + os_arch = static_cast<NaClOSArch>(os_arch + 1); + if (sandbox_isa == "arm") + os_arch = static_cast<NaClOSArch>(os_arch + 2); + + HistogramEnumerate("NaCl.Client.OSArch", os_arch, kNaClOSArchMax, -1); +} + +void HistogramEnumerateLoadStatus(PluginErrorCode error_code) { + HistogramEnumerate("NaCl.LoadStatus.Plugin", error_code, ERROR_MAX, + ERROR_UNKNOWN); +} + +void HistogramEnumerateSelLdrLoadStatus(NaClErrorCode error_code) { + HistogramEnumerate("NaCl.LoadStatus.SelLdr", error_code, NACL_ERROR_CODE_MAX, + LOAD_STATUS_UNKNOWN); +} + +void HistogramEnumerateManifestIsDataURI(bool is_data_uri) { + HistogramEnumerate("NaCl.Manifest.IsDataURI", is_data_uri, 2, -1); +} + +// Derive a class from pp::Find_Dev to forward PPP_Find_Dev calls to +// the plugin. +class FindAdapter : public pp::Find_Dev { + public: + explicit FindAdapter(Plugin* plugin) + : pp::Find_Dev(plugin), + plugin_(plugin) { + BrowserPpp* proxy = plugin_->ppapi_proxy(); + CHECK(proxy != NULL); + ppp_find_ = static_cast<const PPP_Find_Dev*>( + proxy->GetPluginInterface(PPP_FIND_DEV_INTERFACE)); + } + + bool StartFind(const std::string& text, bool case_sensitive) { + if (ppp_find_ != NULL) { + PP_Bool pp_success = + ppp_find_->StartFind(plugin_->pp_instance(), + text.c_str(), + PP_FromBool(case_sensitive)); + return pp_success == PP_TRUE; + } + return false; + } + + void SelectFindResult(bool forward) { + if (ppp_find_ != NULL) { + ppp_find_->SelectFindResult(plugin_->pp_instance(), + PP_FromBool(forward)); + } + } + + void StopFind() { + if (ppp_find_ != NULL) + ppp_find_->StopFind(plugin_->pp_instance()); + } + + private: + Plugin* plugin_; + const PPP_Find_Dev* ppp_find_; + + NACL_DISALLOW_COPY_AND_ASSIGN(FindAdapter); +}; + + +// Derive a class from pp::Printing_Dev to forward PPP_Printing_Dev calls to +// the plugin. +class PrintingAdapter : public pp::Printing_Dev { + public: + explicit PrintingAdapter(Plugin* plugin) + : pp::Printing_Dev(plugin), + plugin_(plugin) { + BrowserPpp* proxy = plugin_->ppapi_proxy(); + CHECK(proxy != NULL); + ppp_printing_ = static_cast<const PPP_Printing_Dev*>( + proxy->GetPluginInterface(PPP_PRINTING_DEV_INTERFACE)); + } + + PP_PrintOutputFormat_Dev* + QuerySupportedPrintOutputFormats(uint32_t* format_count) { + if (ppp_printing_ != NULL) { + return ppp_printing_->QuerySupportedFormats(plugin_->pp_instance(), + format_count); + } + *format_count = 0; + return NULL; + } + + int32_t PrintBegin(const PP_PrintSettings_Dev& print_settings) { + if (ppp_printing_ != NULL) { + return ppp_printing_->Begin(plugin_->pp_instance(), &print_settings); + } + return 0; + } + + pp::Resource PrintPages(const PP_PrintPageNumberRange_Dev* page_ranges, + uint32_t page_range_count) { + if (ppp_printing_ != NULL) { + PP_Resource image_data = ppp_printing_->PrintPages(plugin_->pp_instance(), + page_ranges, + page_range_count); + return pp::ImageData(pp::ImageData::PassRef(), image_data); + } + return pp::Resource(); + } + + void PrintEnd() { + if (ppp_printing_ != NULL) + ppp_printing_->End(plugin_->pp_instance()); + } + + private: + Plugin* plugin_; + const PPP_Printing_Dev* ppp_printing_; + + NACL_DISALLOW_COPY_AND_ASSIGN(PrintingAdapter); +}; + + +// Derive a class from pp::Selection_Dev to forward PPP_Selection_Dev calls to +// the plugin. +class SelectionAdapter : public pp::Selection_Dev { + public: + explicit SelectionAdapter(Plugin* plugin) + : pp::Selection_Dev(plugin), + plugin_(plugin) { + BrowserPpp* proxy = plugin_->ppapi_proxy(); + CHECK(proxy != NULL); + ppp_selection_ = static_cast<const PPP_Selection_Dev*>( + proxy->GetPluginInterface(PPP_SELECTION_DEV_INTERFACE)); + } + + pp::Var GetSelectedText(bool html) { + if (ppp_selection_ != NULL) { + PP_Var var = ppp_selection_->GetSelectedText(plugin_->pp_instance(), + PP_FromBool(html)); + return pp::Var(pp::Var::PassRef(), var); + } + return pp::Var(); + } + + private: + Plugin* plugin_; + const PPP_Selection_Dev* ppp_selection_; + + NACL_DISALLOW_COPY_AND_ASSIGN(SelectionAdapter); +}; + + +// Derive a class from pp::WidgetClient_Dev to forward PPP_Widget_Dev +// and PPP_Scrollbar_Dev calls to the plugin. +class WidgetClientAdapter : public pp::WidgetClient_Dev { + public: + explicit WidgetClientAdapter(Plugin* plugin) + : pp::WidgetClient_Dev(plugin), + plugin_(plugin) { + BrowserPpp* proxy = plugin_->ppapi_proxy(); + CHECK(proxy != NULL); + ppp_widget_ = static_cast<const PPP_Widget_Dev*>( + proxy->GetPluginInterface(PPP_WIDGET_DEV_INTERFACE)); + ppp_scrollbar_ = static_cast<const PPP_Scrollbar_Dev*>( + proxy->GetPluginInterface(PPP_SCROLLBAR_DEV_INTERFACE)); + } + + void InvalidateWidget(pp::Widget_Dev widget, const pp::Rect& dirty_rect) { + if (ppp_widget_ != NULL) { + ppp_widget_->Invalidate(plugin_->pp_instance(), + widget.pp_resource(), + &dirty_rect.pp_rect()); + } + } + + void ScrollbarValueChanged(pp::Scrollbar_Dev scrollbar, uint32_t value) { + if (ppp_scrollbar_ != NULL) { + ppp_scrollbar_->ValueChanged(plugin_->pp_instance(), + scrollbar.pp_resource(), + value); + } + } + + void ScrollbarOverlayChanged(pp::Scrollbar_Dev scrollbar, bool overlay) { + if (ppp_scrollbar_ != NULL) { + ppp_scrollbar_->OverlayChanged(plugin_->pp_instance(), + scrollbar.pp_resource(), + PP_FromBool(overlay)); + } + } + + private: + Plugin* plugin_; + const PPP_Widget_Dev* ppp_widget_; + const PPP_Scrollbar_Dev* ppp_scrollbar_; + + NACL_DISALLOW_COPY_AND_ASSIGN(WidgetClientAdapter); +}; + + +// Derive a class from pp::Zoom_Dev to forward PPP_Zoom_Dev calls to +// the plugin. +class ZoomAdapter : public pp::Zoom_Dev { + public: + explicit ZoomAdapter(Plugin* plugin) + : pp::Zoom_Dev(plugin), + plugin_(plugin) { + BrowserPpp* proxy = plugin_->ppapi_proxy(); + CHECK(proxy != NULL); + ppp_zoom_ = static_cast<const PPP_Zoom_Dev*>( + proxy->GetPluginInterface(PPP_ZOOM_DEV_INTERFACE)); + } + + void Zoom(double factor, bool text_only) { + if (ppp_zoom_ != NULL) { + ppp_zoom_->Zoom(plugin_->pp_instance(), + factor, + PP_FromBool(text_only)); + } + } + + private: + Plugin* plugin_; + const PPP_Zoom_Dev* ppp_zoom_; + + NACL_DISALLOW_COPY_AND_ASSIGN(ZoomAdapter); +}; + +} // namespace + +bool Plugin::ExperimentalJavaScriptApisAreEnabled() { + return getenv("NACL_ENABLE_EXPERIMENTAL_JAVASCRIPT_APIS") != NULL; +} + +static int const kAbiHeaderBuffer = 256; // must be at least EI_ABIVERSION + 1 + +void Plugin::LoadMethods() { + PLUGIN_PRINTF(("Plugin::LoadMethods ()\n")); + // Properties implemented by Plugin. + AddPropertyGet(GetReadyStateProperty, "readyState", "i"); +} + +bool Plugin::HasMethod(uintptr_t method_id, CallType call_type) { + PLUGIN_PRINTF(("Plugin::HasMethod (method_id=%x) = ", + static_cast<int>(method_id))); + if (GetMethodInfo(method_id, call_type)) { + PLUGIN_PRINTF(("true\n")); + return true; + } + if (!ExperimentalJavaScriptApisAreEnabled()) { + PLUGIN_PRINTF(("false\n")); + return false; + } + if (call_type != METHOD_CALL) { + // SRPC nexes can only export methods. + PLUGIN_PRINTF(("false\n")); + return false; + } + bool has_method = main_subprocess_.HasMethod(method_id); + PLUGIN_PRINTF(("%s\n", (has_method ? "true" : "false"))); + return has_method; +} + +bool Plugin::InitParams(uintptr_t method_id, + CallType call_type, + SrpcParams* params) { + MethodInfo* method_info = GetMethodInfo(method_id, call_type); + PLUGIN_PRINTF(("Plugin::InitParams (id=%"NACL_PRIxPTR", method_info=%p)\n", + method_id, method_info)); + if (NULL != method_info) { + return params->Init(method_info->ins(), method_info->outs()); + } + if (!ExperimentalJavaScriptApisAreEnabled()) { + return false; + } + if (call_type != METHOD_CALL) { + // SRPC nexes can only export methods. + return false; + } + return main_subprocess_.InitParams(method_id, params); +} + +bool Plugin::Invoke(uintptr_t method_id, + CallType call_type, + SrpcParams* params) { + MethodInfo* method_info = GetMethodInfo(method_id, call_type); + + if (NULL != method_info && NULL != method_info->function_ptr()) { + return method_info->function_ptr()(static_cast<void*>(this), params); + } + if (!ExperimentalJavaScriptApisAreEnabled()) { + return false; + } + if (call_type != METHOD_CALL) { + // SRPC nexes can only export methods. + return false; + } + return main_subprocess_.Invoke(method_id, params); +} + +bool Plugin::Init(BrowserInterface* browser_interface, + int argc, + char* argn[], + char* argv[]) { + PLUGIN_PRINTF(("Plugin::Init (instance=%p)\n", static_cast<void*>(this))); + + browser_interface_ = browser_interface; + // Remember the embed/object argn/argv pairs. + argn_ = new(std::nothrow) char*[argc]; + argv_ = new(std::nothrow) char*[argc]; + argc_ = 0; + for (int i = 0; i < argc; ++i) { + if (NULL != argn_ && NULL != argv_) { + argn_[argc_] = strdup(argn[i]); + argv_[argc_] = strdup(argv[i]); + if (NULL == argn_[argc_] || NULL == argv_[argc_]) { + // Give up on passing arguments. + free(argn_[argc_]); + free(argv_[argc_]); + continue; + } + ++argc_; + } + } + // TODO(sehr): this leaks strings if there is a subsequent failure. + + // Set up the factory used to produce DescWrappers. + wrapper_factory_ = new nacl::DescWrapperFactory(); + if (NULL == wrapper_factory_) { + return false; + } + PLUGIN_PRINTF(("Plugin::Init (wrapper_factory=%p)\n", + static_cast<void*>(wrapper_factory_))); + + // Set up the scriptable methods for the plugin. + LoadMethods(); + + PLUGIN_PRINTF(("Plugin::Init (return 1)\n")); + // Return success. + return true; +} + +void Plugin::ShutDownSubprocesses() { + PLUGIN_PRINTF(("Plugin::ShutDownSubprocesses (this=%p)\n", + static_cast<void*>(this))); + PLUGIN_PRINTF(("Plugin::ShutDownSubprocesses (%s)\n", + main_subprocess_.detailed_description().c_str())); + + // Shutdown service runtime. This must be done before all other calls so + // they don't block forever when waiting for the upcall thread to exit. + main_subprocess_.Shutdown(); + for (size_t i = 0; i < nacl_subprocesses_.size(); ++i) { + PLUGIN_PRINTF(("Plugin::ShutDownSubprocesses (%s)\n", + nacl_subprocesses_[i]->detailed_description().c_str())); + delete nacl_subprocesses_[i]; + } + nacl_subprocesses_.clear(); + + PLUGIN_PRINTF(("Plugin::ShutDownSubprocess (this=%p, return)\n", + static_cast<void*>(this))); +} + +bool Plugin::LoadNaClModuleCommon(nacl::DescWrapper* wrapper, + NaClSubprocess* subprocess, + ErrorInfo* error_info, + pp::CompletionCallback init_done_cb) { + ServiceRuntime* new_service_runtime = new(std::nothrow) ServiceRuntime( + this, + init_done_cb); + subprocess->set_service_runtime(new_service_runtime); + PLUGIN_PRINTF(("Plugin::LoadNaClModuleCommon (service_runtime=%p)\n", + static_cast<void*>(new_service_runtime))); + if (NULL == new_service_runtime) { + error_info->SetReport(ERROR_SEL_LDR_INIT, + "sel_ldr init failure " + subprocess->description()); + return false; + } + + bool service_runtime_started = + new_service_runtime->Start(wrapper, error_info); + PLUGIN_PRINTF(("Plugin::LoadNaClModuleCommon (service_runtime_started=%d)\n", + service_runtime_started)); + if (!service_runtime_started) { + return false; + } + return true; +} + +bool Plugin::StartSrpcServicesCommon(NaClSubprocess* subprocess, + ErrorInfo* error_info) { + if (!subprocess->StartSrpcServices()) { + error_info->SetReport(ERROR_SRPC_CONNECTION_FAIL, + "SRPC connection failure for " + + subprocess->description()); + return false; + } + PLUGIN_PRINTF(("Plugin::StartSrpcServicesCommon (established srpc_client " + "%p)\n", + static_cast<void*>(subprocess->srpc_client()))); + return true; +} + +bool Plugin::StartSrpcServices(NaClSubprocess* subprocess, + ErrorInfo* error_info) { + if (!StartSrpcServicesCommon(subprocess, error_info)) { + return false; + } + // TODO(jvoung): This next bit is likely not needed... + // If StartSrpcServices is only in the JS API that is just for SRPC nexes + // (namely __startSrpcServices), then attempts to start the JS proxy + // will fail anyway? + // If that is the case, by removing the following line, + // the StartSrpcServices == StartSrpcServicesCommon. + // We still need this function though, to launch helper SRPC nexes within + // the plugin. + return StartJSObjectProxy(subprocess, error_info); +} + +bool Plugin::StartJSObjectProxy(NaClSubprocess* subprocess, + ErrorInfo* error_info) { + if (!subprocess->StartJSObjectProxy(this, error_info)) { + // TODO(sehr,polina): rename the function and env var + // to ExperimentalJavaScriptApisAreEnabled. + if (error_info->error_code() == ERROR_START_PROXY_CHECK_PPP && + ExperimentalJavaScriptApisAreEnabled()) { + // It is not an error for the proxy to fail to find PPP methods if + // experimental APIs are enabled. This means we have an SRPC nexe. + error_info->Reset(); + } else { + return false; + } + } + return true; +} + +bool Plugin::LoadNaClModule(nacl::DescWrapper* wrapper, + ErrorInfo* error_info, + pp::CompletionCallback init_done_cb) { + // Before forking a new sel_ldr process, ensure that we do not leak + // the ServiceRuntime object for an existing subprocess, and that any + // associated listener threads do not go unjoined because if they + // outlive the Plugin object, they will not be memory safe. + ShutDownSubprocesses(); + if (!(LoadNaClModuleCommon(wrapper, &main_subprocess_, error_info, + init_done_cb))) { + return false; + } + PLUGIN_PRINTF(("Plugin::LoadNaClModule (%s)\n", + main_subprocess_.detailed_description().c_str())); + return true; +} + +bool Plugin::LoadNaClModuleContinuationIntern(ErrorInfo* error_info) { + if (!(StartSrpcServicesCommon(&main_subprocess_, error_info) + && StartJSObjectProxy(&main_subprocess_, error_info))) { + return false; + } + PLUGIN_PRINTF(("Plugin::LoadNaClModule (%s)\n", + main_subprocess_.detailed_description().c_str())); + return true; +} + +NaClSubprocessId Plugin::LoadHelperNaClModule(nacl::DescWrapper* wrapper, + ErrorInfo* error_info) { + NaClSubprocessId next_id = next_nacl_subprocess_id(); + nacl::scoped_ptr<NaClSubprocess> nacl_subprocess( + new(std::nothrow) NaClSubprocess(next_id, NULL, NULL)); + if (NULL == nacl_subprocess.get()) { + error_info->SetReport(ERROR_SEL_LDR_INIT, + "unable to allocate helper subprocess."); + return kInvalidNaClSubprocessId; + } + + if (!(LoadNaClModuleCommon(wrapper, nacl_subprocess.get(), error_info, + pp::BlockUntilComplete()) + // We need not wait for the init_done callback. We can block + // here in StartSrpcServicesCommon, since helper NaCl modules + // are spawned from a private thread. + // + // NB: More refactoring might be needed, however, if helper + // NaCl modules have their own manifest. Currently the + // manifest is a per-plugin-instance object, not a per + // NaClSubprocess object. + && StartSrpcServicesCommon(nacl_subprocess.get(), error_info))) { + return kInvalidNaClSubprocessId; + } + + PLUGIN_PRINTF(("Plugin::LoadHelperNaClModule (%s)\n", + nacl_subprocess.get()->detailed_description().c_str())); + + nacl_subprocesses_.push_back(nacl_subprocess.release()); + return next_id; +} + +char* Plugin::LookupArgument(const char* key) { + char** keys = argn(); + for (int ii = 0, len = argc(); ii < len; ++ii) { + if (!strcmp(keys[ii], key)) { + return argv()[ii]; + } + } + return NULL; +} + +void Plugin::AddPropertyGet(RpcFunction function_ptr, + const char* name, + const char* outs) { + uintptr_t method_id = browser_interface()->StringToIdentifier(name); + PLUGIN_PRINTF(("Plugin::AddPropertyGet (name='%s', id=%" + NACL_PRIxPTR")\n", name, method_id)); + MethodInfo* new_method = new MethodInfo(function_ptr, name, "", outs); + property_get_methods_.AddMethod(method_id, new_method); +} + +MethodInfo* Plugin::GetMethodInfo(uintptr_t method_id, CallType call_type) { + MethodInfo* method_info = NULL; + switch (call_type) { + case PROPERTY_GET: + method_info = property_get_methods_.GetMethod(method_id); + break; + case PROPERTY_SET: + case METHOD_CALL: + break; + } + PLUGIN_PRINTF(("Plugin::GetMethodInfo (id=%"NACL_PRIxPTR", " + "return %p)\n", method_id, static_cast<void*>(method_info))); + return method_info; +} + +class ProgressEvent { + public: + ProgressEvent(const char* event_type, + Plugin::LengthComputable length_computable, + uint64_t loaded_bytes, + uint64_t total_bytes) : + event_type_(event_type), + length_computable_(length_computable), + loaded_bytes_(loaded_bytes), + total_bytes_(total_bytes) { } + const char* event_type() const { return event_type_; } + Plugin::LengthComputable length_computable() const { + return length_computable_; + } + uint64_t loaded_bytes() const { return loaded_bytes_; } + uint64_t total_bytes() const { return total_bytes_; } + + private: + // event_type_ is always passed from a string literal, so ownership is + // not taken. Hence it does not need to be deleted when ProgressEvent is + // destroyed. + const char* event_type_; + Plugin::LengthComputable length_computable_; + uint64_t loaded_bytes_; + uint64_t total_bytes_; +}; + +const char* const Plugin::kNaClMIMEType = "application/x-nacl"; + +bool Plugin::IsForeignMIMEType() const { + return + !mime_type().empty() && + mime_type() != kNaClMIMEType; +} + + +Plugin* Plugin::New(PP_Instance pp_instance) { + PLUGIN_PRINTF(("Plugin::New (pp_instance=%"NACL_PRId32")\n", pp_instance)); +#if NACL_WINDOWS && !defined(NACL_STANDALONE) + if (!NaClHandlePassBrowserCtor()) { + return NULL; + } +#endif + Plugin* plugin = new(std::nothrow) Plugin(pp_instance); + PLUGIN_PRINTF(("Plugin::New (plugin=%p)\n", static_cast<void*>(plugin))); + if (plugin == NULL) { + return NULL; + } + return plugin; +} + + +// All failures of this function will show up as "Missing Plugin-in", so +// there is no need to log to JS console that there was an initialization +// failure. Note that module loading functions will log their own errors. +bool Plugin::Init(uint32_t argc, const char* argn[], const char* argv[]) { + PLUGIN_PRINTF(("Plugin::Init (argc=%"NACL_PRIu32")\n", argc)); + HistogramEnumerateOsArch(GetSandboxISA()); + init_time_ = NaClGetTimeOfDayMicroseconds(); + + BrowserInterface* browser_interface = new(std::nothrow) BrowserInterface; + if (browser_interface == NULL) { + return false; + } + ScriptableHandle* handle = ScriptableHandle::NewPlugin(this); + if (handle == NULL) { + return false; + } + set_scriptable_handle(handle); + PLUGIN_PRINTF(("Plugin::Init (scriptable_handle=%p)\n", + static_cast<void*>(scriptable_handle()))); + url_util_ = pp::URLUtil_Dev::Get(); + if (url_util_ == NULL) { + return false; + } + PLUGIN_PRINTF(("Plugin::Init (url_util_=%p)\n", + static_cast<const void*>(url_util_))); + + bool status = Plugin::Init( + browser_interface, + static_cast<int>(argc), + // TODO(polina): Can we change the args on our end to be const to + // avoid these ugly casts? + const_cast<char**>(argn), + const_cast<char**>(argv)); + if (status) { + const char* type_attr = LookupArgument(kTypeAttribute); + if (type_attr != NULL) { + mime_type_ = nacl::string(type_attr); + std::transform(mime_type_.begin(), mime_type_.end(), mime_type_.begin(), + tolower); + } + + const char* manifest_url = LookupArgument(kSrcManifestAttribute); + // If the MIME type is foreign, then 'src' will be the URL for the content + // and 'nacl' will be the URL for the manifest. + if (IsForeignMIMEType()) { + manifest_url = LookupArgument(kNaClManifestAttribute); + enable_dev_interface_ = RequiresDevInterface(manifest_url); + } + // Use the document URL as the base for resolving relative URLs to find the + // manifest. This takes into account the setting of <base> tags that + // precede the embed/object. + CHECK(url_util_ != NULL); + pp::Var base_var = url_util_->GetDocumentURL(*this); + if (!base_var.is_string()) { + PLUGIN_PRINTF(("Plugin::Init (unable to find document url)\n")); + return false; + } + set_plugin_base_url(base_var.AsString()); + if (manifest_url == NULL) { + // TODO(sehr,polina): this should be a hard error when scripting + // the src property is no longer allowed. + PLUGIN_PRINTF(("Plugin::Init:" + " WARNING: no 'src' property, so no manifest loaded.\n")); + if (NULL != LookupArgument(kNaClManifestAttribute)) { + PLUGIN_PRINTF(("Plugin::Init:" + " WARNING: 'nacl' property is incorrect. Use 'src'.\n")); + } + } else { + // Issue a GET for the manifest_url. The manifest file will be parsed to + // determine the nexe URL. + // Sets src property to full manifest URL. + RequestNaClManifest(manifest_url); + } + } + + // Export a property to allow us to get the last error description. + AddPropertyGet(GetLastError, "lastError", "s"); + + PLUGIN_PRINTF(("Plugin::Init (status=%d)\n", status)); + return status; +} + + +Plugin::Plugin(PP_Instance pp_instance) + : pp::InstancePrivate(pp_instance), + browser_interface_(NULL), + scriptable_handle_(NULL), + argc_(-1), + argn_(NULL), + argv_(NULL), + main_subprocess_(kMainSubprocessId, NULL, NULL), + nacl_ready_state_(UNSENT), + wrapper_factory_(NULL), + last_error_string_(""), + ppapi_proxy_(NULL), + enable_dev_interface_(false), + replayDidChangeView(false), + replayHandleDocumentLoad(false), + init_time_(0), + ready_time_(0), + nexe_size_(0) { + PLUGIN_PRINTF(("Plugin::Plugin (this=%p, pp_instance=%" + NACL_PRId32")\n", static_cast<void*>(this), pp_instance)); + NaClSrpcModuleInit(); + nexe_downloader_.Initialize(this); + pnacl_.Initialize(this); + callback_factory_.Initialize(this); +} + + +Plugin::~Plugin() { + int64_t shutdown_start = NaClGetTimeOfDayMicroseconds(); + + PLUGIN_PRINTF(("Plugin::~Plugin (this=%p, scriptable_handle=%p)\n", + static_cast<void*>(this), + static_cast<void*>(scriptable_handle()))); + + // If the proxy has been shutdown before now, it's likely the plugin suffered + // an error while loading. + if (ppapi_proxy_ != NULL) { + HistogramTimeLarge( + "NaCl.ModuleUptime.Normal", + (shutdown_start - ready_time_) / NACL_MICROS_PER_MILLI); + } + +#if NACL_WINDOWS && !defined(NACL_STANDALONE) + NaClHandlePassBrowserDtor(); +#endif + + url_downloaders_.erase(url_downloaders_.begin(), url_downloaders_.end()); + + ShutdownProxy(); + ScriptableHandle* scriptable_handle_ = scriptable_handle(); + ScriptableHandle::Unref(&scriptable_handle_); + NaClSrpcModuleFini(); + + // TODO(sehr,polina): We should not need to call ShutDownSubprocesses() here. + ShutDownSubprocesses(); + + delete wrapper_factory_; + delete browser_interface_; + delete[] argv_; + delete[] argn_; + + HistogramTimeSmall( + "NaCl.Perf.ShutdownTime.Total", + (NaClGetTimeOfDayMicroseconds() - shutdown_start) + / NACL_MICROS_PER_MILLI); + + PLUGIN_PRINTF(("Plugin::~Plugin (this=%p, return)\n", + static_cast<void*>(this))); +} + + +void Plugin::DidChangeView(const pp::Rect& position, const pp::Rect& clip) { + PLUGIN_PRINTF(("Plugin::DidChangeView (this=%p)\n", + static_cast<void*>(this))); + + if (!BrowserPpp::is_valid(ppapi_proxy_)) { + // Store this event and replay it when the proxy becomes available. + replayDidChangeView = true; + replayDidChangeViewPosition = position; + replayDidChangeViewClip = clip; + return; + } else { + ppapi_proxy_->ppp_instance_interface()->DidChangeView( + pp_instance(), &(position.pp_rect()), &(clip.pp_rect())); + } +} + + +void Plugin::DidChangeFocus(bool has_focus) { + PLUGIN_PRINTF(("Plugin::DidChangeFocus (this=%p)\n", + static_cast<void*>(this))); + if (!BrowserPpp::is_valid(ppapi_proxy_)) { + return; + } else { + ppapi_proxy_->ppp_instance_interface()->DidChangeFocus( + pp_instance(), PP_FromBool(has_focus)); + } +} + + +bool Plugin::HandleInputEvent(const pp::InputEvent& event) { + PLUGIN_PRINTF(("Plugin::HandleInputEvent (this=%p)\n", + static_cast<void*>(this))); + if (!BrowserPpp::is_valid(ppapi_proxy_) || + ppapi_proxy_->ppp_input_event_interface() == NULL) { + return false; // event is not handled here. + } else { + bool handled = PP_ToBool( + ppapi_proxy_->ppp_input_event_interface()->HandleInputEvent( + pp_instance(), event.pp_resource())); + PLUGIN_PRINTF(("Plugin::HandleInputEvent (handled=%d)\n", handled)); + return handled; + } +} + + +bool Plugin::HandleDocumentLoad(const pp::URLLoader& url_loader) { + PLUGIN_PRINTF(("Plugin::HandleDocumentLoad (this=%p)\n", + static_cast<void*>(this))); + if (!BrowserPpp::is_valid(ppapi_proxy_)) { + // Store this event and replay it when the proxy becomes available. + replayHandleDocumentLoad = true; + replayHandleDocumentLoadURLLoader = url_loader; + // Return true so that the browser keeps servicing this loader so we can + // perform requests on it later. + return true; + } else { + return PP_ToBool( + ppapi_proxy_->ppp_instance_interface()->HandleDocumentLoad( + pp_instance(), url_loader.pp_resource())); + } +} + + +void Plugin::HandleMessage(const pp::Var& message) { + PLUGIN_PRINTF(("Plugin::HandleMessage (this=%p)\n", + static_cast<void*>(this))); + if (BrowserPpp::is_valid(ppapi_proxy_) && + ppapi_proxy_->ppp_messaging_interface() != NULL) { + ppapi_proxy_->ppp_messaging_interface()->HandleMessage( + pp_instance(), message.pp_var()); + } +} + + +pp::Var Plugin::GetInstanceObject() { + PLUGIN_PRINTF(("Plugin::GetInstanceObject (this=%p)\n", + static_cast<void*>(this))); + // The browser will unref when it discards the var for this object. + ScriptableHandle* handle = + static_cast<ScriptableHandle*>(scriptable_handle()->AddRef()); + pp::Var* handle_var = handle->var(); + PLUGIN_PRINTF(("Plugin::GetInstanceObject (handle=%p, handle_var=%p)\n", + static_cast<void*>(handle), static_cast<void*>(handle_var))); + return *handle_var; // make a copy +} + +void Plugin::HistogramStartupTimeSmall(const std::string& name, float dt) { + if (nexe_size_ > 0) { + float size_in_MB = static_cast<float>(nexe_size_) / (1024.f * 1024.f); + HistogramTimeSmall(name, static_cast<int64_t>(dt)); + HistogramTimeSmall(name + "PerMB", static_cast<int64_t>(dt / size_in_MB)); + } +} + +void Plugin::HistogramStartupTimeMedium(const std::string& name, float dt) { + if (nexe_size_ > 0) { + float size_in_MB = static_cast<float>(nexe_size_) / (1024.f * 1024.f); + HistogramTimeMedium(name, static_cast<int64_t>(dt)); + HistogramTimeMedium(name + "PerMB", static_cast<int64_t>(dt / size_in_MB)); + } +} + +void Plugin::NexeFileDidOpen(int32_t pp_error) { + PLUGIN_PRINTF(("Plugin::NexeFileDidOpen (pp_error=%"NACL_PRId32")\n", + pp_error)); + int32_t file_desc = nexe_downloader_.GetPOSIXFileDescriptor(); + PLUGIN_PRINTF(("Plugin::NexeFileDidOpen (file_desc=%"NACL_PRId32")\n", + file_desc)); + ErrorInfo error_info; + if (pp_error != PP_OK || file_desc == NACL_NO_FILE_DESC) { + if (pp_error == PP_ERROR_ABORTED) { + ReportLoadAbort(); + } else { + error_info.SetReport(ERROR_NEXE_LOAD_URL, "could not load nexe url."); + ReportLoadError(error_info); + } + return; + } + int32_t file_desc_ok_to_close = DUP(file_desc); + if (file_desc_ok_to_close == NACL_NO_FILE_DESC) { + error_info.SetReport(ERROR_NEXE_FH_DUP, + "could not duplicate loaded file handle."); + ReportLoadError(error_info); + return; + } + struct stat stat_buf; + if (0 != fstat(file_desc_ok_to_close, &stat_buf)) { + CLOSE(file_desc_ok_to_close); + error_info.SetReport(ERROR_NEXE_STAT, "could not stat nexe file."); + ReportLoadError(error_info); + return; + } + size_t nexe_bytes_read = static_cast<size_t>(stat_buf.st_size); + + nexe_size_ = nexe_bytes_read; + HistogramSizeKB("NaCl.Perf.Size.Nexe", + static_cast<int32_t>(nexe_size_ / 1024)); + HistogramStartupTimeMedium( + "NaCl.Perf.StartupTime.NexeDownload", + static_cast<float>(nexe_downloader_.TimeSinceOpenMilliseconds())); + + // Inform JavaScript that we successfully downloaded the nacl module. + EnqueueProgressEvent("progress", + LENGTH_IS_COMPUTABLE, + nexe_bytes_read, + nexe_bytes_read); + + load_start_ = NaClGetTimeOfDayMicroseconds(); + nacl::scoped_ptr<nacl::DescWrapper> + wrapper(wrapper_factory()->MakeFileDesc(file_desc_ok_to_close, O_RDONLY)); + NaClLog(4, "NexeFileDidOpen: invoking LoadNaClModule\n"); + bool was_successful = LoadNaClModule( + wrapper.get(), &error_info, + callback_factory_.NewCallback(&Plugin::NexeFileDidOpenContinuation)); + + if (!was_successful) { + ReportLoadError(error_info); + } +} + +void Plugin::NexeFileDidOpenContinuation(int32_t pp_error) { + ErrorInfo error_info; + bool was_successful; + + UNREFERENCED_PARAMETER(pp_error); + NaClLog(4, "Entered NexeFileDidOpenContinuation\n"); + NaClLog(4, "NexeFileDidOpenContinuation: invoking" + " LoadNaClModuleContinuationIntern\n"); + was_successful = LoadNaClModuleContinuationIntern(&error_info); + if (was_successful) { + NaClLog(4, "NexeFileDidOpenContinuation: success;" + " setting histograms\n"); + ready_time_ = NaClGetTimeOfDayMicroseconds(); + HistogramStartupTimeSmall( + "NaCl.Perf.StartupTime.LoadModule", + static_cast<float>(ready_time_ - load_start_) / NACL_MICROS_PER_MILLI); + HistogramStartupTimeMedium( + "NaCl.Perf.StartupTime.Total", + static_cast<float>(ready_time_ - init_time_) / NACL_MICROS_PER_MILLI); + + ReportLoadSuccess(LENGTH_IS_COMPUTABLE, nexe_size_, nexe_size_); + } else { + NaClLog(4, "NexeFileDidOpenContinuation: failed."); + ReportLoadError(error_info); + } + NaClLog(4, "Leaving NexeFileDidOpenContinuation\n"); +} + +void Plugin::BitcodeDidTranslate(int32_t pp_error) { + PLUGIN_PRINTF(("Plugin::BitcodeDidTranslate (pp_error=%"NACL_PRId32")\n", + pp_error)); + if (pp_error != PP_OK) { + // Error should have been reported by pnacl. Just return. + PLUGIN_PRINTF(("Plugin::BitcodeDidTranslate error in Pnacl\n")); + return; + } + // Inform JavaScript that we successfully translated the bitcode to a nexe. + EnqueueProgressEvent("progress", + LENGTH_IS_NOT_COMPUTABLE, + kUnknownBytes, + kUnknownBytes); + nacl::scoped_ptr<nacl::DescWrapper> + wrapper(pnacl_.ReleaseTranslatedFD()); + ErrorInfo error_info; + bool was_successful = LoadNaClModule( + wrapper.get(), &error_info, + callback_factory_.NewCallback(&Plugin::BitcodeDidTranslateContinuation)); + + if (!was_successful) { + ReportLoadError(error_info); + } +} + +void Plugin::BitcodeDidTranslateContinuation(int32_t pp_error) { + ErrorInfo error_info; + bool was_successful = LoadNaClModuleContinuationIntern(&error_info); + + NaClLog(4, "Entered BitcodeDidTranslateContinuation\n"); + UNREFERENCED_PARAMETER(pp_error); + if (was_successful) { + ReportLoadSuccess(LENGTH_IS_NOT_COMPUTABLE, + kUnknownBytes, + kUnknownBytes); + } else { + ReportLoadError(error_info); + } +} + +// Check manifest_url and return whether or not to enable PPAPI Dev interfaces. +// Returning true here will enable the PPAPI Dev interfaces regardless of +// the environment variable NACL_ENABLE_PPAPI_DEV. +bool Plugin::RequiresDevInterface(const nacl::string& manifest_url) { + const char* extensions[] = { + "chrome-extension://acadkphlmlegjaadjagenfimbpphcgnh/", // PDF + }; + for (size_t i = 0; i < sizeof(extensions) / sizeof(const char*); ++i) { + if (manifest_url.find(extensions[i]) == 0) { + return true; + } + } + return false; +} + +bool Plugin::StartProxiedExecution(NaClSrpcChannel* srpc_channel, + ErrorInfo* error_info) { + PLUGIN_PRINTF(("Plugin::StartProxiedExecution (srpc_channel=%p)\n", + static_cast<void*>(srpc_channel))); + + // Log the amound of time that has passed between the trusted plugin being + // initialized and the untrusted plugin being initialized. This is (roughly) + // the cost of using NaCl, in terms of startup time. + HistogramStartupTimeMedium( + "NaCl.Perf.StartupTime.NaClOverhead", + static_cast<float>(NaClGetTimeOfDayMicroseconds() - init_time_) + / NACL_MICROS_PER_MILLI); + + // Check that the .nexe exports the PPAPI intialization method. + NaClSrpcService* client_service = srpc_channel->client; + if (NaClSrpcServiceMethodIndex(client_service, + "PPP_InitializeModule:iihs:ii") == + kNaClSrpcInvalidMethodIndex) { + error_info->SetReport( + ERROR_START_PROXY_CHECK_PPP, + "could not find PPP_InitializeModule() - toolchain version mismatch?"); + PLUGIN_PRINTF(("Plugin::StartProxiedExecution (%s)\n", + error_info->message().c_str())); + return false; + } + nacl::scoped_ptr<BrowserPpp> ppapi_proxy( + new(std::nothrow) BrowserPpp(srpc_channel, this)); + PLUGIN_PRINTF(("Plugin::StartProxiedExecution (ppapi_proxy=%p)\n", + static_cast<void*>(ppapi_proxy.get()))); + if (ppapi_proxy.get() == NULL) { + error_info->SetReport(ERROR_START_PROXY_ALLOC, + "could not allocate proxy memory."); + return false; + } + pp::Module* module = pp::Module::Get(); + PLUGIN_PRINTF(("Plugin::StartProxiedExecution (module=%p)\n", + static_cast<void*>(module))); + CHECK(module != NULL); // We could not have gotten past init stage otherwise. + int32_t pp_error = + ppapi_proxy->InitializeModule(module->pp_module(), + module->get_browser_interface()); + PLUGIN_PRINTF(("Plugin::StartProxiedExecution (pp_error=%" + NACL_PRId32")\n", pp_error)); + if (pp_error != PP_OK) { + error_info->SetReport(ERROR_START_PROXY_MODULE, + "could not initialize module."); + return false; + } + const PPP_Instance* instance_interface = + ppapi_proxy->ppp_instance_interface(); + PLUGIN_PRINTF(("Plugin::StartProxiedExecution (ppp_instance=%p)\n", + static_cast<const void*>(instance_interface))); + CHECK(instance_interface != NULL); // Verified on module initialization. + PP_Bool did_create = instance_interface->DidCreate( + pp_instance(), + argc(), + const_cast<const char**>(argn()), + const_cast<const char**>(argv())); + PLUGIN_PRINTF(("Plugin::StartProxiedExecution (did_create=%d)\n", + did_create)); + if (did_create == PP_FALSE) { + error_info->SetReport(ERROR_START_PROXY_INSTANCE, + "could not create instance."); + return false; + } + + ppapi_proxy_ = ppapi_proxy.release(); + + // Create PPP* interface adapters to forward calls to .nexe. + find_adapter_.reset(new(std::nothrow) FindAdapter(this)); + printing_adapter_.reset(new(std::nothrow) PrintingAdapter(this)); + selection_adapter_.reset(new(std::nothrow) SelectionAdapter(this)); + widget_client_adapter_.reset(new(std::nothrow) WidgetClientAdapter(this)); + zoom_adapter_.reset(new(std::nothrow) ZoomAdapter(this)); + + // Replay missed events. + if (replayDidChangeView) { + replayDidChangeView = false; + DidChangeView(replayDidChangeViewPosition, replayDidChangeViewClip); + } + if (replayHandleDocumentLoad) { + replayHandleDocumentLoad = false; + HandleDocumentLoad(replayHandleDocumentLoadURLLoader); + // Release our reference on this loader. + replayHandleDocumentLoadURLLoader = pp::URLLoader(); + } + bool is_valid_proxy = BrowserPpp::is_valid(ppapi_proxy_); + PLUGIN_PRINTF(("Plugin::StartProxiedExecution (is_valid_proxy=%d)\n", + is_valid_proxy)); + if (!is_valid_proxy) { + error_info->SetReport(ERROR_START_PROXY_CRASH, + "instance crashed after creation."); + } + return is_valid_proxy; +} + +void Plugin::ReportDeadNexe() { + PLUGIN_PRINTF(("Plugin::ReportDeadNexe\n")); + + if (nacl_ready_state() == DONE) { // After loadEnd. + int64_t crash_time = NaClGetTimeOfDayMicroseconds(); + // Crashes will be more likely near startup, so use a medium histogram + // instead of a large one. + HistogramTimeMedium( + "NaCl.ModuleUptime.Crash", + (crash_time - ready_time_) / NACL_MICROS_PER_MILLI); + + EnqueueProgressEvent("crash", + LENGTH_IS_NOT_COMPUTABLE, + kUnknownBytes, + kUnknownBytes); + CHECK(ppapi_proxy_ != NULL && !ppapi_proxy_->is_valid()); + ShutdownProxy(); + } + // else LoadNaClModule and NexeFileDidOpen will provide error handling. + // NOTE: not all crashes during load will make it here. + // Those in BrowserPpp::InitializeModule and creation of PPP interfaces + // will just get reported back as PP_ERROR_FAILED. +} + +void Plugin::ShutdownProxy() { + PLUGIN_PRINTF(("Plugin::ShutdownProxy (ppapi_proxy=%p)\n", + static_cast<void*>(ppapi_proxy_))); + // We do not call remote PPP_Instance::DidDestroy because the untrusted + // side can no longer take full advantage of mostly asynchronous Pepper + // per-Instance interfaces at this point. + if (BrowserPpp::is_valid(ppapi_proxy_)) + ppapi_proxy_->ShutdownModule(); + delete ppapi_proxy_; + ppapi_proxy_ = NULL; +} + +void Plugin::NaClManifestBufferReady(int32_t pp_error) { + PLUGIN_PRINTF(("Plugin::NaClManifestBufferReady (pp_error=%" + NACL_PRId32")\n", pp_error)); + ErrorInfo error_info; + set_manifest_url(nexe_downloader_.url()); + if (pp_error != PP_OK) { + if (pp_error == PP_ERROR_ABORTED) { + ReportLoadAbort(); + } else { + error_info.SetReport(ERROR_MANIFEST_LOAD_URL, + "could not load manifest url."); + ReportLoadError(error_info); + } + return; + } + + const std::deque<char>& buffer = nexe_downloader_.buffer(); + size_t buffer_size = buffer.size(); + if (buffer_size > kNaClManifestMaxFileBytes) { + error_info.SetReport(ERROR_MANIFEST_TOO_LARGE, + "manifest file too large."); + ReportLoadError(error_info); + return; + } + nacl::scoped_array<char> json_buffer(new char[buffer_size + 1]); + if (json_buffer == NULL) { + error_info.SetReport(ERROR_MANIFEST_MEMORY_ALLOC, + "could not allocate manifest memory."); + ReportLoadError(error_info); + return; + } + std::copy(buffer.begin(), buffer.begin() + buffer_size, &json_buffer[0]); + json_buffer[buffer_size] = '\0'; + + ProcessNaClManifest(json_buffer.get()); +} + +void Plugin::NaClManifestFileDidOpen(int32_t pp_error) { + PLUGIN_PRINTF(("Plugin::NaClManifestFileDidOpen (pp_error=%" + NACL_PRId32")\n", pp_error)); + HistogramTimeSmall("NaCl.Perf.StartupTime.ManifestDownload", + nexe_downloader_.TimeSinceOpenMilliseconds()); + ErrorInfo error_info; + // The manifest file was successfully opened. Set the src property on the + // plugin now, so that the full url is available to error handlers. + set_manifest_url(nexe_downloader_.url()); + int32_t file_desc = nexe_downloader_.GetPOSIXFileDescriptor(); + PLUGIN_PRINTF(("Plugin::NaClManifestFileDidOpen (file_desc=%" + NACL_PRId32")\n", file_desc)); + if (pp_error != PP_OK || file_desc == NACL_NO_FILE_DESC) { + if (pp_error == PP_ERROR_ABORTED) { + ReportLoadAbort(); + } else { + error_info.SetReport(ERROR_MANIFEST_LOAD_URL, + "could not load manifest url."); + ReportLoadError(error_info); + } + return; + } + // Duplicate the file descriptor in order to create a FILE stream with it + // that can later be closed without closing the original descriptor. The + // browser will take care of the original descriptor. + int dup_file_desc = DUP(file_desc); + struct stat stat_buf; + if (0 != fstat(dup_file_desc, &stat_buf)) { + CLOSE(dup_file_desc); + error_info.SetReport(ERROR_MANIFEST_STAT, + "could not stat manifest file."); + ReportLoadError(error_info); + return; + } + size_t bytes_to_read = static_cast<size_t>(stat_buf.st_size); + if (bytes_to_read > kNaClManifestMaxFileBytes) { + CLOSE(dup_file_desc); + error_info.SetReport(ERROR_MANIFEST_TOO_LARGE, + "manifest file too large."); + ReportLoadError(error_info); + return; + } + FILE* json_file = fdopen(dup_file_desc, "rb"); + PLUGIN_PRINTF(("Plugin::NaClManifestFileDidOpen " + "(dup_file_desc=%"NACL_PRId32", json_file=%p)\n", + dup_file_desc, static_cast<void*>(json_file))); + if (json_file == NULL) { + CLOSE(dup_file_desc); + error_info.SetReport(ERROR_MANIFEST_OPEN, + "could not open manifest file."); + ReportLoadError(error_info); + return; + } + nacl::scoped_array<char> json_buffer(new char[bytes_to_read + 1]); + if (json_buffer == NULL) { + fclose(json_file); + error_info.SetReport(ERROR_MANIFEST_MEMORY_ALLOC, + "could not allocate manifest memory."); + ReportLoadError(error_info); + return; + } + // json_buffer could hold a large enough buffer that the system might need + // multiple reads to fill it, so iterate through reads. + size_t total_bytes_read = 0; + while (0 < bytes_to_read) { + size_t bytes_this_read = fread(&json_buffer[total_bytes_read], + sizeof(char), + bytes_to_read, + json_file); + if (bytes_this_read < bytes_to_read && + (feof(json_file) || ferror(json_file))) { + PLUGIN_PRINTF(("Plugin::NaClManifestFileDidOpen failed: " + "total_bytes_read=%"NACL_PRIuS" " + "bytes_to_read=%"NACL_PRIuS"\n", + total_bytes_read, bytes_to_read)); + fclose(json_file); + error_info.SetReport(ERROR_MANIFEST_READ, + "could not read manifest file."); + ReportLoadError(error_info); + return; + } + total_bytes_read += bytes_this_read; + bytes_to_read -= bytes_this_read; + } + // Once the bytes are read, the FILE is no longer needed, so close it. This + // allows for early returns without leaking the |json_file| FILE object. + fclose(json_file); + // No need to close |file_desc|, that is handled by |nexe_downloader_|. + json_buffer[total_bytes_read] = '\0'; // Force null termination. + + ProcessNaClManifest(json_buffer.get()); +} + +void Plugin::ProcessNaClManifest(const nacl::string& manifest_json) { + HistogramSizeKB("NaCl.Perf.Size.Manifest", + static_cast<int32_t>(manifest_json.length() / 1024)); + nacl::string program_url; + bool is_portable; + ErrorInfo error_info; + if (!SetManifestObject(manifest_json, &error_info)) { + ReportLoadError(error_info); + return; + } + + if (SelectProgramURLFromManifest(&program_url, &error_info, &is_portable)) { + set_nacl_ready_state(LOADING); + // Inform JavaScript that we found a nexe URL to load. + EnqueueProgressEvent("progress", + LENGTH_IS_NOT_COMPUTABLE, + kUnknownBytes, + kUnknownBytes); + if (is_portable) { + // TODO(jvoung): Do we want to check an ENV var if pnacl is enabled first? + nacl::string llc_url; + nacl::string ld_url; + if (SelectLLCURLFromManifest(&llc_url, &error_info) && + SelectLDURLFromManifest(&ld_url, &error_info)) { + pp::CompletionCallback translate_callback = + callback_factory_.NewCallback(&Plugin::BitcodeDidTranslate); + // Will always call the callback on success or failure. + pnacl_.BitcodeToNative(program_url, + llc_url, + ld_url, + translate_callback); + return; + } + } else { + pp::CompletionCallback open_callback = + callback_factory_.NewRequiredCallback(&Plugin::NexeFileDidOpen); + // Will always call the callback on success or failure. + CHECK( + nexe_downloader_.Open(program_url, DOWNLOAD_TO_FILE, open_callback)); + return; + } + } + // Failed to select the program and/or the translator. + ReportLoadError(error_info); +} + +void Plugin::RequestNaClManifest(const nacl::string& url) { + PLUGIN_PRINTF(("Plugin::RequestNaClManifest (url='%s')\n", url.c_str())); + PLUGIN_PRINTF(("Plugin::RequestNaClManifest (plugin base url='%s')\n", + plugin_base_url().c_str())); + // The full URL of the manifest file is relative to the base url. + CHECK(url_util_ != NULL); + pp::Var nmf_resolved_url = + url_util_->ResolveRelativeToURL(plugin_base_url(), pp::Var(url)); + if (!nmf_resolved_url.is_string()) { + ErrorInfo error_info; + error_info.SetReport( + ERROR_MANIFEST_RESOLVE_URL, + nacl::string("could not resolve URL \"") + url.c_str() + + "\" relative to \"" + plugin_base_url().c_str() + "\"."); + ReportLoadError(error_info); + return; + } + PLUGIN_PRINTF(("Plugin::RequestNaClManifest (resolved url='%s')\n", + nmf_resolved_url.AsString().c_str())); + set_manifest_base_url(nmf_resolved_url.AsString()); + set_manifest_url(url); + // Inform JavaScript that a load is starting. + set_nacl_ready_state(OPENED); + EnqueueProgressEvent("loadstart", + LENGTH_IS_NOT_COMPUTABLE, + kUnknownBytes, + kUnknownBytes); + bool is_data_uri = GetUrlScheme(nmf_resolved_url.AsString()) == SCHEME_DATA; + HistogramEnumerateManifestIsDataURI(static_cast<int>(is_data_uri)); + if (is_data_uri) { + pp::CompletionCallback open_callback = + callback_factory_.NewRequiredCallback(&Plugin::NaClManifestBufferReady); + // Will always call the callback on success or failure. + CHECK(nexe_downloader_.Open(nmf_resolved_url.AsString(), + DOWNLOAD_TO_BUFFER, + open_callback)); + } else { + pp::CompletionCallback open_callback = + callback_factory_.NewRequiredCallback(&Plugin::NaClManifestFileDidOpen); + // Will always call the callback on success or failure. + CHECK(nexe_downloader_.Open(nmf_resolved_url.AsString(), + DOWNLOAD_TO_FILE, + open_callback)); + } +} + + +bool Plugin::SetManifestObject(const nacl::string& manifest_json, + ErrorInfo* error_info) { + PLUGIN_PRINTF(("Plugin::SetManifestObject(): manifest_json='%s'.\n", + manifest_json.c_str())); + if (error_info == NULL) + return false; + manifest_.reset( + new Manifest(url_util_, manifest_base_url(), GetSandboxISA())); + if (!manifest_->Init(manifest_json, error_info)) { + return false; + } + return true; +} + +bool Plugin::SelectProgramURLFromManifest(nacl::string* result, + ErrorInfo* error_info, + bool* is_portable) { + const nacl::string sandbox_isa(GetSandboxISA()); + PLUGIN_PRINTF(("Plugin::SelectProgramURLFromManifest(): sandbox='%s'.\n", + sandbox_isa.c_str())); + if (result == NULL || error_info == NULL || manifest_ == NULL) + return false; + return manifest_->GetProgramURL(result, error_info, is_portable); +} + +// TODO(jvoung): get rid of these when we have a better hosting solution +// for PNaCl's nexes. +bool Plugin::SelectLLCURLFromManifest(nacl::string* result, + ErrorInfo* error_info) { + PLUGIN_PRINTF(("Plugin::SelectLLCURLFromManifest()\n")); + if (result == NULL || error_info == NULL || manifest_ == NULL) + return false; + return manifest_->GetLLCURL(result, error_info); +} + +bool Plugin::SelectLDURLFromManifest(nacl::string* result, + ErrorInfo* error_info) { + PLUGIN_PRINTF(("Plugin::SelectLDURLFromManifest()\n")); + if (result == NULL || error_info == NULL || manifest_ == NULL) + return false; + return manifest_->GetLDURL(result, error_info); +} +// end TODO(jvoung) + + +void Plugin::UrlDidOpenForStreamAsFile(int32_t pp_error, + FileDownloader*& url_downloader, + PP_CompletionCallback callback) { + PLUGIN_PRINTF(("Plugin::UrlDidOpen (pp_error=%"NACL_PRId32 + ", url_downloader=%p)\n", pp_error, + static_cast<void*>(url_downloader))); + url_downloaders_.erase(url_downloader); + nacl::scoped_ptr<FileDownloader> scoped_url_downloader(url_downloader); + int32_t file_desc = scoped_url_downloader->GetPOSIXFileDescriptor(); + + if (pp_error != PP_OK) { + PP_RunCompletionCallback(&callback, pp_error); + } else if (file_desc > NACL_NO_FILE_DESC) { + url_fd_map_[url_downloader->url_to_open()] = file_desc; + PP_RunCompletionCallback(&callback, PP_OK); + } else { + PP_RunCompletionCallback(&callback, PP_ERROR_FAILED); + } +} + +int32_t Plugin::GetPOSIXFileDesc(const nacl::string& url) { + PLUGIN_PRINTF(("Plugin::GetFileDesc (url=%s)\n", url.c_str())); + int32_t file_desc_ok_to_close = NACL_NO_FILE_DESC; + std::map<nacl::string, int32_t>::iterator it = url_fd_map_.find(url); + if (it != url_fd_map_.end()) + file_desc_ok_to_close = DUP(it->second); + return file_desc_ok_to_close; +} + + +bool Plugin::StreamAsFile(const nacl::string& url, + PP_CompletionCallback callback) { + PLUGIN_PRINTF(("Plugin::StreamAsFile (url='%s')\n", url.c_str())); + FileDownloader* downloader = new FileDownloader(); + downloader->Initialize(this); + url_downloaders_.insert(downloader); + pp::CompletionCallback open_callback = + callback_factory_.NewRequiredCallback( + &Plugin::UrlDidOpenForStreamAsFile, downloader, callback); + // Untrusted loads are always relative to the page's origin. + CHECK(url_util_ != NULL); + pp::Var resolved_url = + url_util_->ResolveRelativeToURL(pp::Var(plugin_base_url()), url); + if (!resolved_url.is_string()) { + PLUGIN_PRINTF(("Plugin::StreamAsFile: " + "could not resolve url \"%s\" relative to plugin \"%s\".", + url.c_str(), + plugin_base_url().c_str())); + return false; + } + // If true, will always call the callback on success or failure. + return downloader->Open(url, DOWNLOAD_TO_FILE, open_callback); +} + +#ifndef HACK_FOR_MACOS_HANG_REMOVED +// The following is needed to avoid a plugin startup hang in the +// MacOS "chrome_browser_tests under gyp" stage. +// TODO(sehr,mseaborn): remove this hack. +void (plugin::Plugin::*pmem)(int32_t, + plugin::FileDownloader*&, + pp::VarPrivate&); +void Plugin::XYZZY(const nacl::string& url, + pp::VarPrivate js_callback) { + UNREFERENCED_PARAMETER(url); + UNREFERENCED_PARAMETER(js_callback); + pp::CompletionCallback open_callback = + callback_factory_.NewRequiredCallback(pmem, + reinterpret_cast<plugin::FileDownloader*>(NULL), + js_callback); +} +#endif // HACK_FOR_MACOS_HANG_REMOVED + + +void Plugin::ReportLoadSuccess(LengthComputable length_computable, + uint64_t loaded_bytes, + uint64_t total_bytes) { + // Set the readyState attribute to indicate loaded. + set_nacl_ready_state(DONE); + // Inform JavaScript that loading was successful and is complete. + EnqueueProgressEvent("load", length_computable, loaded_bytes, total_bytes); + EnqueueProgressEvent("loadend", length_computable, loaded_bytes, total_bytes); + + // UMA + HistogramEnumerateLoadStatus(ERROR_LOAD_SUCCESS); +} + + +// TODO(ncbray): report UMA stats +void Plugin::ReportLoadError(const ErrorInfo& error_info) { + PLUGIN_PRINTF(("Plugin::ReportLoadError (error='%s')\n", + error_info.message().c_str())); + // Set the readyState attribute to indicate we need to start over. + set_nacl_ready_state(DONE); + // Report an error in lastError and on the JavaScript console. + nacl::string message = nacl::string("NaCl module load failed: ") + + error_info.message(); + set_last_error_string(message); + browser_interface()->AddToConsole(this, message); + ShutdownProxy(); + // Inform JavaScript that loading encountered an error and is complete. + EnqueueProgressEvent("error", + LENGTH_IS_NOT_COMPUTABLE, + kUnknownBytes, + kUnknownBytes); + EnqueueProgressEvent("loadend", + LENGTH_IS_NOT_COMPUTABLE, + kUnknownBytes, + kUnknownBytes); + + // UMA + HistogramEnumerateLoadStatus(error_info.error_code()); +} + + +void Plugin::ReportLoadAbort() { + PLUGIN_PRINTF(("Plugin::ReportLoadAbort\n")); + // Set the readyState attribute to indicate we need to start over. + set_nacl_ready_state(DONE); + // Report an error in lastError and on the JavaScript console. + nacl::string error_string("NaCl module load failed: user aborted"); + set_last_error_string(error_string); + browser_interface()->AddToConsole(this, error_string); + ShutdownProxy(); + // Inform JavaScript that loading was aborted and is complete. + EnqueueProgressEvent("abort", + LENGTH_IS_NOT_COMPUTABLE, + kUnknownBytes, + kUnknownBytes); + EnqueueProgressEvent("loadend", + LENGTH_IS_NOT_COMPUTABLE, + kUnknownBytes, + kUnknownBytes); + + // UMA + HistogramEnumerateLoadStatus(ERROR_LOAD_ABORTED); +} + + +void Plugin::EnqueueProgressEvent(const char* event_type, + LengthComputable length_computable, + uint64_t loaded_bytes, + uint64_t total_bytes) { + PLUGIN_PRINTF(("Plugin::EnqueueProgressEvent (" + "event_type='%s', length_computable=%d, " + "loaded=%"NACL_PRIu64", total=%"NACL_PRIu64")\n", + event_type, + static_cast<int>(length_computable), + loaded_bytes, + total_bytes)); + + progress_events_.push(new ProgressEvent(event_type, + length_computable, + loaded_bytes, + total_bytes)); + // Note that using callback_factory_ in this way is not thread safe. + // If/when EnqueueProgressEvent is callable from another thread, this + // will need to change. + pp::CompletionCallback callback = + callback_factory_.NewCallback(&Plugin::DispatchProgressEvent); + pp::Core* core = pp::Module::Get()->core(); + core->CallOnMainThread(0, callback, 0); +} + +void Plugin::ReportSelLdrLoadStatus(int status) { + HistogramEnumerateSelLdrLoadStatus(static_cast<NaClErrorCode>(status)); +} + +void Plugin::DispatchProgressEvent(int32_t result) { + PLUGIN_PRINTF(("Plugin::DispatchProgressEvent (result=%" + NACL_PRId32")\n", result)); + if (result < 0) { + return; + } + if (progress_events_.empty()) { + PLUGIN_PRINTF(("Plugin::DispatchProgressEvent: no pending events\n")); + return; + } + nacl::scoped_ptr<ProgressEvent> event(progress_events_.front()); + progress_events_.pop(); + PLUGIN_PRINTF(("Plugin::DispatchProgressEvent (" + "event_type='%s', length_computable=%d, " + "loaded=%"NACL_PRIu64", total=%"NACL_PRIu64")\n", + event->event_type(), + static_cast<int>(event->length_computable()), + event->loaded_bytes(), + event->total_bytes())); + + static const char* kEventClosureJS = + "(function(target, type, lengthComputable, loadedBytes, totalBytes) {" + " var progress_event = document.createEvent('ProgressEvent');" + " progress_event.initProgressEvent(type, false, true," + " lengthComputable," + " loadedBytes," + " totalBytes);" + " target.dispatchEvent(progress_event);" + "})"; + + // Create a function object by evaluating the JavaScript text. + // TODO(sehr, polina): We should probably cache the created function object to + // avoid JavaScript reparsing. + pp::VarPrivate exception; + pp::VarPrivate function_object = ExecuteScript(kEventClosureJS, &exception); + if (!exception.is_undefined() || !function_object.is_object()) { + PLUGIN_PRINTF(("Plugin::DispatchProgressEvent:" + " Function object creation failed.\n")); + return; + } + // Get the target of the event to be dispatched. + pp::Var owner_element_object = GetOwnerElementObject(); + if (!owner_element_object.is_object()) { + PLUGIN_PRINTF(("Plugin::DispatchProgressEvent:" + " Couldn't get owner element object.\n")); + NACL_NOTREACHED(); + return; + } + + pp::Var argv[5]; + static const uint32_t argc = NACL_ARRAY_SIZE(argv); + argv[0] = owner_element_object; + argv[1] = pp::Var(event->event_type()); + argv[2] = pp::Var(event->length_computable() == LENGTH_IS_COMPUTABLE); + argv[3] = pp::Var(static_cast<double>(event->loaded_bytes())); + argv[4] = pp::Var(static_cast<double>(event->total_bytes())); + + // Dispatch the event. + const pp::Var default_method; + function_object.Call(default_method, argc, argv, &exception); + if (!exception.is_undefined()) { + PLUGIN_PRINTF(("Plugin::DispatchProgressEvent:" + " event dispatch failed.\n")); + } +} + +UrlSchemeType Plugin::GetUrlScheme(const std::string& url) { + CHECK(url_util_ != NULL); + PP_URLComponents_Dev comps; + pp::Var canonicalized = + url_util_->Canonicalize(pp::Var(url), &comps); + + if (canonicalized.is_null() || + (comps.scheme.begin == 0 && comps.scheme.len == -1)) { + // |url| was an invalid URL or has no scheme. + return SCHEME_OTHER; + } + + CHECK(comps.scheme.begin < + static_cast<int>(canonicalized.AsString().size())); + CHECK(comps.scheme.begin + comps.scheme.len < + static_cast<int>(canonicalized.AsString().size())); + + std::string scheme = canonicalized.AsString().substr(comps.scheme.begin, + comps.scheme.len); + if (scheme == kChromeExtensionUriScheme) + return SCHEME_CHROME_EXTENSION; + if (scheme == kDataUriScheme) + return SCHEME_DATA; + return SCHEME_OTHER; +} + +} // namespace plugin diff --git a/ppapi/native_client/src/trusted/plugin/plugin.gyp b/ppapi/native_client/src/trusted/plugin/plugin.gyp new file mode 100644 index 0000000..8aee36d --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/plugin.gyp @@ -0,0 +1,135 @@ +# -*- python -*- +# 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. + +{ + 'includes': [ + 'plugin.gypi', + ], + 'target_defaults': { + 'variables': { + 'target_base': 'none', + }, + 'include_dirs': [ + '<(DEPTH)/ppapi', + ], + 'target_conditions': [ + ['target_base=="ppNaClPlugin"', { + 'sources': [ + '<@(common_sources)', + ], + 'xcode_settings': { + 'WARNING_CFLAGS!': [ + # TODO(bradnelson): remove -pedantic when --std=c++98 in common.gypi + '-pedantic', + ], + 'WARNING_CFLAGS': [ + '-Wno-deprecated', + '-Wno-deprecated-declarations', + ], + }, + 'conditions': [ + ['OS=="win"', { + 'sources': [ + 'win/nacl_plugin.rc', + ], + 'msvs_settings': { + 'VCCLCompilerTool': { + 'ExceptionHandling': '2', # /EHsc + }, + 'VCLinkerTool': { + 'AdditionalLibraryDirectories': [ + '$(OutDir)/lib', + ], + }, + }, + }], + ], + }], + ], + }, + 'targets': [], + 'conditions': [ + ['nacl_standalone==1', { + 'targets': [ + { + 'target_name': 'ppGoogleNaClPlugin', + 'type': 'shared_library', + 'variables': { + 'target_base': 'ppNaClPlugin', + }, + 'dependencies': [ + '<(DEPTH)/native_client/src/shared/gio/gio.gyp:gio', + '<(DEPTH)/native_client/src/shared/imc/imc.gyp:imc', + '<(DEPTH)/native_client/src/shared/platform/platform.gyp:platform', + '<(DEPTH)/native_client/src/shared/ppapi/ppapi.gyp:ppapi_cpp_nacl', + '<(DEPTH)/ppapi/native_client/src/shared/ppapi_proxy/ppapi_proxy.gyp:nacl_ppapi_browser', + '<(DEPTH)/native_client/src/shared/srpc/srpc.gyp:nonnacl_srpc', + '<(DEPTH)/native_client/src/shared/srpc/srpc.gyp:nonnacl_srpc', + '<(DEPTH)/native_client/src/third_party_mod/jsoncpp/jsoncpp.gyp:jsoncpp', + '<(DEPTH)/native_client/src/trusted/desc/desc.gyp:nrd_xfer', + '<(DEPTH)/native_client/src/trusted/nonnacl_util/nonnacl_util.gyp:nonnacl_util', + '<(DEPTH)/native_client/src/trusted/platform_qualify/platform_qualify.gyp:platform_qual_lib', + '<(DEPTH)/native_client/src/trusted/gio/gio_wrapped_desc.gyp:gio_wrapped_desc', + '<(DEPTH)/native_client/src/trusted/simple_service/simple_service.gyp:simple_service', + '<(DEPTH)/native_client/src/trusted/reverse_service/reverse_service.gyp:reverse_service', + '<(DEPTH)/native_client/src/trusted/weak_ref/weak_ref.gyp:weak_ref', + ], + }], + }], + ['nacl_standalone==0', { + 'targets': [ + { + 'target_name': 'ppGoogleNaClPluginChrome', + 'type': 'loadable_module', + 'sources': [ + '<@(common_sources)', + 'browser_utils.cc', + ], + 'xcode_settings': { + 'OTHER_LDFLAGS': [ + '-Wl,-exported_symbols_list <(DEPTH)/native_client/src/trusted/plugin/ppapi.def' + ], + }, + 'dependencies': [ + '<(DEPTH)/native_client/src/shared/gio/gio.gyp:gio', + '<(DEPTH)/native_client/src/shared/imc/imc.gyp:imc', + '<(DEPTH)/native_client/src/shared/platform/platform.gyp:platform', + '<(DEPTH)/native_client/src/shared/ppapi/ppapi.gyp:ppapi_cpp_nacl', + '<(DEPTH)/ppapi/native_client/src/shared/ppapi_proxy/ppapi_proxy.gyp:nacl_ppapi_browser', + '<(DEPTH)/native_client/src/shared/srpc/srpc.gyp:nonnacl_srpc', + '<(DEPTH)/native_client/src/third_party_mod/jsoncpp/jsoncpp.gyp:jsoncpp', + '<(DEPTH)/native_client/src/trusted/desc/desc.gyp:nrd_xfer', + '<(DEPTH)/native_client/src/trusted/nonnacl_util/nonnacl_util.gyp:nonnacl_util', + '<(DEPTH)/native_client/src/trusted/platform_qualify/platform_qualify.gyp:platform_qual_lib', + '<(DEPTH)/native_client/src/trusted/gio/gio_wrapped_desc.gyp:gio_wrapped_desc', + '<(DEPTH)/native_client/src/trusted/simple_service/simple_service.gyp:simple_service', + '<(DEPTH)/native_client/src/trusted/reverse_service/reverse_service.gyp:reverse_service', + '<(DEPTH)/native_client/src/trusted/weak_ref/weak_ref.gyp:weak_ref', + ], + 'conditions': [ + ['OS=="mac"', { + 'mac_bundle': 1, + 'product_name': 'ppGoogleNaClPluginChrome', + 'product_extension': 'plugin', + }], + ['OS=="mac" and mac_breakpad==1', { + 'variables': { + # A real .dSYM is needed for dump_syms to operate on. + 'mac_real_dsym': 1, + }, + }], + ['OS=="win"', { + 'dependencies': [ + '<(DEPTH)/native_client/src/trusted/handle_pass/handle_pass.gyp:browserhandle', + '<(DEPTH)/native_client/src/trusted/handle_pass/handle_pass.gyp:handle_lookup', + '<(DEPTH)/native_client/src/trusted/handle_pass/handle_pass.gyp:ldrhandle', + ], + }], + ], + }, + ], + }], + ], +} diff --git a/ppapi/native_client/src/trusted/plugin/plugin.gypi b/ppapi/native_client/src/trusted/plugin/plugin.gypi new file mode 100644 index 0000000..4048b18 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/plugin.gypi @@ -0,0 +1,105 @@ +# 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. + +{ + 'variables': { + 'common_sources': [ + 'array_ppapi.cc', + 'browser_interface.cc', + 'desc_based_handle.cc', + 'file_downloader.cc', + 'manifest.cc', + 'method_map.cc', + 'module_ppapi.cc', + 'nacl_subprocess.cc', + 'nexe_arch.cc', + 'plugin.cc', + 'pnacl_coordinator.cc', + 'pnacl_srpc_lib.cc', + 'scriptable_handle.cc', + 'service_runtime.cc', + 'srpc_client.cc', + 'string_encoding.cc', + 'utility.cc', + 'var_utils.cc', + ], + # Append the arch-specific ISA code to common_sources. + 'conditions': [ + # Note: this test assumes that if this is not an ARM build, then this is + # is an x86 build. This is because |target_arch| for x86 can be one of a + # number of values (x64, ia32, etc.). + ['target_arch=="arm"', { + 'common_sources': [ + 'arch_arm/sandbox_isa.cc', + ], + }, { # else: 'target_arch != "arm" + 'common_sources': [ + 'arch_x86/sandbox_isa.cc', + ], + }], + ], + }, + 'includes': [ + '../../../build/common.gypi', + ], + 'target_defaults': { + 'variables': { + 'target_platform': 'none', + }, + 'conditions': [ + ['OS=="linux"', { + 'defines': [ + 'XP_UNIX', + 'MOZ_X11', + ], + 'cflags': [ + '-Wno-long-long', + ], + 'ldflags': [ + # Catch unresolved symbols. + '-Wl,-z,defs', + ], + 'libraries': [ + '-ldl', + '-lX11', + '-lXt', + ], + }], + ['OS=="mac"', { + 'defines': [ + 'XP_MACOSX', + 'XP_UNIX', + 'TARGET_API_MAC_CARBON=1', + 'NO_X11', + 'USE_SYSTEM_CONSOLE', + ], + 'cflags': [ + '-Wno-long-long', + ], + 'link_settings': { + 'libraries': [ + '$(SDKROOT)/System/Library/Frameworks/Carbon.framework', + ], + }, + }], + ['OS=="win"', { + 'defines': [ + 'XP_WIN', + 'WIN32', + '_WINDOWS' + ], + 'flags': [ + '-fPIC', + '-Wno-long-long', + ], + 'link_settings': { + 'libraries': [ + '-lgdi32.lib', + '-luser32.lib', + ], + }, + }], + ], + }, +} diff --git a/ppapi/native_client/src/trusted/plugin/plugin.h b/ppapi/native_client/src/trusted/plugin/plugin.h new file mode 100644 index 0000000..2df0827 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/plugin.h @@ -0,0 +1,514 @@ +/* + * 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. + */ + +// The portable representation of an instance and root scriptable object. +// The PPAPI version of the plugin instantiates a subclass of this class. + +#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PLUGIN_H_ +#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PLUGIN_H_ + +#include <stdio.h> +#include <map> +#include <set> +#include <queue> +#include <string> +#include <vector> + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/include/nacl_string.h" +#include "native_client/src/trusted/plugin/file_downloader.h" +#include "native_client/src/trusted/plugin/method_map.h" +#include "native_client/src/trusted/plugin/nacl_subprocess.h" +#include "native_client/src/trusted/plugin/pnacl_coordinator.h" +#include "native_client/src/trusted/plugin/service_runtime.h" +#include "native_client/src/trusted/plugin/utility.h" + +#include "ppapi/cpp/private/var_private.h" +// for pp::VarPrivate +#include "ppapi/cpp/private/instance_private.h" +#include "ppapi/cpp/rect.h" +#include "ppapi/cpp/url_loader.h" +#include "ppapi/cpp/var.h" + +struct NaClSrpcChannel; +struct NaClDesc; + +namespace nacl { +class DescWrapper; +class DescWrapperFactory; +} // namespace nacl + +namespace pp { +class Find_Dev; +class Printing_Dev; +class Selection_Dev; +class URLLoader; +class WidgetClient_Dev; +class URLUtil_Dev; +class Zoom_Dev; +} + +namespace ppapi_proxy { +class BrowserPpp; +} + +namespace plugin { + +class ErrorInfo; +class Manifest; +class PnaclCoordinator; +class ProgressEvent; +class ScriptableHandle; + +typedef enum { + METHOD_CALL = 0, + PROPERTY_GET, + PROPERTY_SET +} CallType; + + +class Plugin : public pp::InstancePrivate { + public: + // Factory method for creation. + static Plugin* New(PP_Instance instance); + + // ----- Methods inherited from pp::Instance: + + // Initializes this plugin with <embed/object ...> tag attribute count |argc|, + // names |argn| and values |argn|. Returns false on failure. + // Gets called by the browser right after New(). + virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]); + + // Handles view changes from the browser. + virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip); + + // Handles gaining or losing focus. + virtual void DidChangeFocus(bool has_focus); + + // Handles input events delivered from the browser to this plugin element. + virtual bool HandleInputEvent(const pp::InputEvent& event); + + // Handles gaining or losing focus. + virtual bool HandleDocumentLoad(const pp::URLLoader& url_loader); + + // Returns a scriptable reference to this plugin element. + // Called by JavaScript document.getElementById(plugin_id). + virtual pp::Var GetInstanceObject(); + + // Handles postMessage from browser + virtual void HandleMessage(const pp::Var& message); + + // ----- Plugin interface support. + + // Load support. + // NaCl module can be loaded given a DescWrapper. + // + // Starts NaCl module but does not wait until low-level + // initialization (e.g., ld.so dynamic loading of manifest files) is + // done. The module will become ready later, asynchronously. Other + // event handlers should block until the module is ready before + // trying to communicate with it, i.e., until nacl_ready_state is + // DONE. Note, however, we already have another mechanism that + // prevents event delivery: StartJSObjectProxy plumbs through + // NaClSubprocess to SrpcClient which upcalls + // Plugin::StartProxiedExecution, which sets ppapi_proxy_. And NULL + // == ppapi_proxy_ prevents events from being delivered, even if + // nacl_ready_state is DONE. + // + // NB: currently we do not time out, so if the untrusted code + // does not signal that it is ready, then we will deadlock the main + // thread of the renderer on this subsequent event delivery. We + // should include a time-out at which point we declare the + // nacl_ready_state to be done, and let the normal crash detection + // mechanism(s) take over. + // + // Updates nacl_module_origin() and nacl_module_url(). + bool LoadNaClModule(nacl::DescWrapper* wrapper, ErrorInfo* error_info, + pp::CompletionCallback init_done_cb); + + // Finish hooking interfaces up, after low-level initialization is + // complete. + bool LoadNaClModuleContinuationIntern(ErrorInfo* error_info); + + // Continuation for starting SRPC/JSProxy services as appropriate. + // This is invoked as a callback when the NaCl module makes the + // init_done reverse RPC to tell us that low-level initialization + // such as ld.so processing is done. That initialization requires + // that the main thread be free in order to do Pepper + // main-thread-only operations such as file processing. + bool LoadNaClModuleContinuation(int32_t pp_error); + + // Load support. + // A helper SRPC NaCl module can be loaded given a DescWrapper. + // Blocks until the helper module signals initialization is done. + // Does not update nacl_module_origin(). + // Returns kInvalidNaClSubprocessId or the ID of the new helper NaCl module. + NaClSubprocessId LoadHelperNaClModule(nacl::DescWrapper* wrapper, + ErrorInfo* error_info); + + // Returns the argument value for the specified key, or NULL if not found. + // The callee retains ownership of the result. + char* LookupArgument(const char* key); + + enum LengthComputable { + LENGTH_IS_NOT_COMPUTABLE = 0, + LENGTH_IS_COMPUTABLE = 1 + }; + // Report successful loading of a module. + void ReportLoadSuccess(LengthComputable length_computable, + uint64_t loaded_bytes, + uint64_t total_bytes); + // Report an error that was encountered while loading a module. + void ReportLoadError(const ErrorInfo& error_info); + // Report loading a module was aborted, typically due to user action. + void ReportLoadAbort(); + // Dispatch a JavaScript event to indicate a key step in loading. + // |event_type| is a character string indicating which type of progress + // event (loadstart, progress, error, abort, load, loadend). Events are + // enqueued on the JavaScript event loop, which then calls back through + // DispatchProgressEvent. + void EnqueueProgressEvent(const char* event_type, + LengthComputable length_computable, + uint64_t loaded_bytes, + uint64_t total_bytes); + + // Report the error code that sel_ldr produces when starting a nexe. + void ReportSelLdrLoadStatus(int status); + + // Report nexe death after load to JS and shut down the proxy. + void ReportDeadNexe(); + + // The embed/object tag argument list. + int argc() const { return argc_; } + char** argn() const { return argn_; } + char** argv() const { return argv_; } + + BrowserInterface* browser_interface() const { return browser_interface_; } + Plugin* plugin() const { return const_cast<Plugin*>(this); } + + // URL resolution support. + // plugin_base_url is the URL used for resolving relative URLs used in + // src="...". + nacl::string plugin_base_url() const { return plugin_base_url_; } + void set_plugin_base_url(nacl::string url) { plugin_base_url_ = url; } + // manifest_base_url is the URL used for resolving relative URLs mentioned + // in manifest files. If the manifest is a data URI, this is an empty string. + nacl::string manifest_base_url() const { return manifest_base_url_; } + void set_manifest_base_url(nacl::string url) { manifest_base_url_ = url; } + + // The URL of the manifest file as set by the "src" attribute. + // It is not the fully resolved URL if it was set as relative. + const nacl::string& manifest_url() const { return manifest_url_; } + void set_manifest_url(const nacl::string& manifest_url) { + manifest_url_ = manifest_url; + } + + // The state of readiness of the plugin. + enum ReadyState { + // The trusted plugin begins in this ready state. + UNSENT = 0, + // The manifest file has been requested, but not yet received. + OPENED = 1, + // This state is unused. + HEADERS_RECEIVED = 2, + // The manifest file has been received and the nexe successfully requested. + LOADING = 3, + // The nexe has been loaded and the proxy started, so it is ready for + // interaction with the page. + DONE = 4 + }; + ReadyState nacl_ready_state() const { return nacl_ready_state_; } + void set_nacl_ready_state(ReadyState nacl_ready_state) { + nacl_ready_state_ = nacl_ready_state; + } + + // Get the NaCl module subprocess that was assigned the ID |id|. + NaClSubprocess* nacl_subprocess(NaClSubprocessId id) const { + if (kInvalidNaClSubprocessId == id) { + return NULL; + } + return nacl_subprocesses_[id]; + } + NaClSubprocessId next_nacl_subprocess_id() const { + return static_cast<NaClSubprocessId>(nacl_subprocesses_.size()); + } + + nacl::DescWrapperFactory* wrapper_factory() const { return wrapper_factory_; } + + // Requests a NaCl manifest download from a |url| relative to the page origin. + void RequestNaClManifest(const nacl::string& url); + + // Start up proxied execution of the browser API. + bool StartProxiedExecution(NaClSrpcChannel* srpc_channel, + ErrorInfo* error_info); + + // Determines whether experimental APIs are usable. + static bool ExperimentalJavaScriptApisAreEnabled(); + + // Methods for method and property dispatch. + bool InitParams(uintptr_t method_id, CallType call_type, SrpcParams* params); + bool HasMethod(uintptr_t method_id, CallType call_type); + bool Invoke(uintptr_t method_id, CallType call_type, SrpcParams* params); + std::vector<uintptr_t>* GetPropertyIdentifiers() { + return property_get_methods_.Keys(); + } + + // The size returned when a file download operation is unable to determine + // the size of the file to load. W3C ProgressEvents specify that unknown + // sizes return 0. + static const uint64_t kUnknownBytes = 0; + + // Getter for PPAPI proxy interface. + ppapi_proxy::BrowserPpp* ppapi_proxy() const { return ppapi_proxy_; } + + // Called back by CallOnMainThread. Dispatches the first enqueued progress + // event. + void DispatchProgressEvent(int32_t result); + + // Requests a URL asynchronously resulting in a call to pp_callback with + // a PP_Error indicating status. On success an open file descriptor + // corresponding to the url body is recorded for further lookup. + // This is used by SRPC-based StreamAsFile(). + bool StreamAsFile(const nacl::string& url, PP_CompletionCallback pp_callback); + // Returns an open POSIX file descriptor retrieved by StreamAsFile() + // or NACL_NO_FILE_DESC. The caller must take ownership of the descriptor. + int32_t GetPOSIXFileDesc(const nacl::string& url); + + // A helper function that gets the scheme type for |url|. Uses URLUtil_Dev + // interface which this class has as a member. + UrlSchemeType GetUrlScheme(const std::string& url); + + // Get the text description of the last error reported by the plugin. + const nacl::string& last_error_string() const { return last_error_string_; } + void set_last_error_string(const nacl::string& error) { + last_error_string_ = error; + } + + // The MIME type used to instantiate this instance of the NaCl plugin. + // Typically, the MIME type will be application/x-nacl. However, if the NEXE + // is being used as a content type handler for another content type (such as + // PDF), then this function will return that type. + const nacl::string& mime_type() const { return mime_type_; } + // The default MIME type for the NaCl plugin. + static const char* const kNaClMIMEType; + // Tests if the MIME type is not a NaCl MIME type. + bool IsForeignMIMEType() const; + // Returns true if PPAPI Dev interfaces should be allowed. + bool enable_dev_interface() { return enable_dev_interface_; } + + Manifest const* manifest() const { return manifest_.get(); } + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(Plugin); +#ifndef HACK_FOR_MACOS_HANG_REMOVED + void XYZZY(const nacl::string& url, pp::VarPrivate js_callback); +#endif // HACK_FOR_MACOS_HANG_REMOVED + // Prevent construction and destruction from outside the class: + // must use factory New() method instead. + explicit Plugin(PP_Instance instance); + // The browser will invoke the destructor via the pp::Instance + // pointer to this object, not from base's Delete(). + ~Plugin(); + + bool Init(BrowserInterface* browser_interface, + int argc, + char* argn[], + char* argv[]); + void LoadMethods(); + // Shuts down socket connection, service runtime, and receive thread, + // in this order, for all spun up NaCl module subprocesses. + void ShutDownSubprocesses(); + + ScriptableHandle* scriptable_handle() const { return scriptable_handle_; } + void set_scriptable_handle(ScriptableHandle* scriptable_handle) { + scriptable_handle_ = scriptable_handle; + } + + // Access the service runtime for the main NaCl subprocess. + ServiceRuntime* main_service_runtime() const { + return main_subprocess_.service_runtime(); + } + + // Setting the properties and methods exported. + void AddPropertyGet(RpcFunction function_ptr, + const char* name, + const char* outs); + + // Help load a nacl module, from the file specified in wrapper. + // This will fully initialize the |subprocess| if the load was successful. + bool LoadNaClModuleCommon(nacl::DescWrapper* wrapper, + NaClSubprocess* subprocess, + ErrorInfo* error_info, + pp::CompletionCallback init_done_cb); + bool StartSrpcServices(NaClSubprocess* subprocess, ErrorInfo* error_info); + bool StartSrpcServicesCommon(NaClSubprocess* subprocess, + ErrorInfo* error_info); + bool StartJSObjectProxy(NaClSubprocess* subprocess, ErrorInfo* error_info); + + MethodInfo* GetMethodInfo(uintptr_t method_id, CallType call_type); + + // Check url and decide if PPAPI Dev interfaces are required. + bool RequiresDevInterface(const nacl::string& manifest_url); + + // Callback used when getting the URL for the .nexe file. If the URL loading + // is successful, the file descriptor is opened and can be passed to sel_ldr + // with the sandbox on. + void NexeFileDidOpen(int32_t pp_error); + void NexeFileDidOpenContinuation(int32_t pp_error); + + // Callback used when a .nexe is translated from bitcode. If the translation + // is successful, the file descriptor is opened and can be passed to sel_ldr + // with the sandbox on. + void BitcodeDidTranslate(int32_t pp_error); + void BitcodeDidTranslateContinuation(int32_t pp_error); + + // NaCl ISA selection manifest file support. The manifest file is specified + // using the "nacl" attribute in the <embed> tag. First, the manifest URL (or + // data: URI) is fetched, then the JSON is parsed. Once a valid .nexe is + // chosen for the sandbox ISA, any current service runtime is shut down, the + // .nexe is loaded and run. + + // Callback used when getting the manifest file as a buffer (e.g., data URIs) + void NaClManifestBufferReady(int32_t pp_error); + + // Callback used when getting the manifest file as a local file descriptor. + void NaClManifestFileDidOpen(int32_t pp_error); + + // Processes the JSON manifest string and starts loading the nexe. + void ProcessNaClManifest(const nacl::string& manifest_json); + + // Parses the JSON in |manifest_json| and retains a Manifest in + // |manifest_| for use by subsequent resource lookups. + // On success, |true| is returned and |manifest_| is updated to + // contain a Manifest that is used by SelectNexeURLFromManifest. + // On failure, |false| is returned, and |manifest_| is unchanged. + bool SetManifestObject(const nacl::string& manifest_json, + ErrorInfo* error_info); + + // Determines the URL of the program module appropriate for the NaCl sandbox + // implemented by the installed sel_ldr. The URL is determined from the + // Manifest in |manifest_|. On success, |true| is returned and |result| is + // set to the URL to use for the program, and |is_portable| is set to + // |true| if the program is portable bitcode. + // On failure, |false| is returned. + bool SelectProgramURLFromManifest(nacl::string* result, + ErrorInfo* error_info, + bool* is_portable); + + // TODO(jvoung): get rid of these once we find a better way to store / install + // the pnacl translator nexes. + bool SelectLLCURLFromManifest(nacl::string* result, + ErrorInfo* error_info); + bool SelectLDURLFromManifest(nacl::string* result, + ErrorInfo* error_info); + + // Logs timing information to a UMA histogram, and also logs the same timing + // information divided by the size of the nexe to another histogram. + void HistogramStartupTimeSmall(const std::string& name, float dt); + void HistogramStartupTimeMedium(const std::string& name, float dt); + + // Determines the appropriate nexe for the sandbox and requests a load. + void RequestNexeLoad(); + + // Callback used when loading a URL for SRPC-based StreamAsFile(). + void UrlDidOpenForStreamAsFile(int32_t pp_error, + FileDownloader*& url_downloader, + PP_CompletionCallback pp_callback); + + // Shuts down the proxy for PPAPI nexes. + void ShutdownProxy(); // Nexe shutdown + proxy deletion. + + BrowserInterface* browser_interface_; + ScriptableHandle* scriptable_handle_; + + int argc_; + char** argn_; + char** argv_; + + // Keep track of the NaCl module subprocesses that were spun up in the plugin. + NaClSubprocess main_subprocess_; + std::vector<NaClSubprocess*> nacl_subprocesses_; + + nacl::string plugin_base_url_; + nacl::string manifest_base_url_; + nacl::string manifest_url_; + ReadyState nacl_ready_state_; + + nacl::DescWrapperFactory* wrapper_factory_; + + MethodMap property_get_methods_; + + // File download support. |nexe_downloader_| can be opened with a specific + // callback to run when the file has been downloaded and is opened for + // reading. We use one downloader for all URL downloads to prevent issuing + // multiple GETs that might arrive out of order. For example, this will + // prevent a GET of a NaCl manifest while a .nexe GET is pending. Note that + // this will also prevent simultaneous handling of multiple .nexes on a page. + FileDownloader nexe_downloader_; + pp::CompletionCallbackFactory<Plugin> callback_factory_; + + PnaclCoordinator pnacl_; + + // The manifest dictionary. Used for looking up resources to be loaded. + nacl::scoped_ptr<Manifest> manifest_; + // URL processing interface for use in looking up resources in manifests. + const pp::URLUtil_Dev* url_util_; + + // A string containing the text description of the last error produced by + // this plugin. + nacl::string last_error_string_; + + // A pointer to the browser end of a proxy pattern connecting the + // NaCl plugin to the PPAPI .nexe's PPP interface + // (InitializeModule, Shutdown, and GetInterface). + // TODO(sehr): this should be a scoped_ptr for shutdown. + ppapi_proxy::BrowserPpp* ppapi_proxy_; + + // PPAPI Dev interfaces are disabled by default. + bool enable_dev_interface_; + + // If we get a DidChangeView event before the nexe is loaded, we store it and + // replay it to nexe after it's loaded. + bool replayDidChangeView; + pp::Rect replayDidChangeViewPosition; + pp::Rect replayDidChangeViewClip; + + // If we get a HandleDocumentLoad event before the nexe is loaded, we store + // it and replay it to nexe after it's loaded. + bool replayHandleDocumentLoad; + pp::URLLoader replayHandleDocumentLoadURLLoader; + + nacl::string mime_type_; + + // Keep track of the FileDownloaders created to fetch urls. + std::set<FileDownloader*> url_downloaders_; + // Keep track of file descriptors opened by StreamAsFile(). + // These are owned by the browser. + std::map<nacl::string, int32_t> url_fd_map_; + + // Pending progress events. + std::queue<ProgressEvent*> progress_events_; + + // Adapter class constructors require a reference to 'this', so we can't + // contain them directly. + nacl::scoped_ptr<pp::Find_Dev> find_adapter_; + nacl::scoped_ptr<pp::Printing_Dev> printing_adapter_; + nacl::scoped_ptr<pp::Selection_Dev> selection_adapter_; + nacl::scoped_ptr<pp::WidgetClient_Dev> widget_client_adapter_; + nacl::scoped_ptr<pp::Zoom_Dev> zoom_adapter_; + + // used for NexeFileDidOpenContinuation + int64_t load_start_; + + int64_t init_time_; + int64_t ready_time_; + size_t nexe_size_; +}; + +} // namespace plugin + +#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PLUGIN_H_ diff --git a/ppapi/native_client/src/trusted/plugin/plugin.xcodeproj/project.pbxproj b/ppapi/native_client/src/trusted/plugin/plugin.xcodeproj/project.pbxproj new file mode 100644 index 0000000..677d4ca --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/plugin.xcodeproj/project.pbxproj @@ -0,0 +1,1390 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 0512B675305D3AFD29700B0A /* libnonnacl_srpc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C0C6572D3103B89B48D63313 /* libnonnacl_srpc.a */; }; + 0DB9A2BCA231BDFE130F6B8D /* string_encoding.cc in Sources */ = {isa = PBXBuildFile; fileRef = F6CEFA6C5EF47C924C602649 /* string_encoding.cc */; }; + 1FE2ACF356B68E5995EC8757 /* libssl.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BA633570BC84E88A5485D7F7 /* libssl.dylib */; }; + 23254754DEFBBDEA139453B4 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6840E9858FC08BB95EE1F006 /* Carbon.framework */; }; + 2F4A1B21FBEC65F36E0CB2E7 /* manifest.cc in Sources */ = {isa = PBXBuildFile; fileRef = D33D7B4AB1DE8A51FD613307 /* manifest.cc */; }; + 35E0F7AF811CD3E0FFD3E727 /* libppapi_cpp_nacl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D8B1B1193623AF3C786449A3 /* libppapi_cpp_nacl.a */; }; + 40FD08307E5A8D1798048FEF /* libreverse_service.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B5543B004A4EF5E566475138 /* libreverse_service.a */; }; + 49F0DB4042A7635BED7A3875 /* pnacl_srpc_lib.cc in Sources */ = {isa = PBXBuildFile; fileRef = C39DC96319E734E57E62E3EB /* pnacl_srpc_lib.cc */; }; + 4A53FCC57ED22D39B86D6E00 /* scriptable_handle.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2FA4ECBA9BFD0DFFF24F01EF /* scriptable_handle.cc */; }; + 4FD2B9E03C6000C497DA4238 /* libnacl_ppapi_browser.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC6D23D35097F45E8EDB69E5 /* libnacl_ppapi_browser.a */; }; + 503165674E302823FC6DBE86 /* libthread_interface.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D120F91621BE6927B701B8F6 /* libthread_interface.a */; }; + 50C6C683F64E64D75FDB6A63 /* libjsoncpp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CB4A8509FD7B34E5A1AFF6F /* libjsoncpp.a */; }; + 51ED36800220F9928F8BA8D5 /* method_map.cc in Sources */ = {isa = PBXBuildFile; fileRef = 054122D1AE4E27A7A2B6204B /* method_map.cc */; }; + 5446AC3AFDBDEA2E886FCE38 /* desc_based_handle.cc in Sources */ = {isa = PBXBuildFile; fileRef = F4AD44658ADACBA1AE1C58EB /* desc_based_handle.cc */; }; + 593D357067E80D83F90273A2 /* libsel_ldr_launcher.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A17B539C4A2EA1E34EC86B94 /* libsel_ldr_launcher.a */; }; + 5DDFB212A1B5455284BDB727 /* nacl_subprocess.cc in Sources */ = {isa = PBXBuildFile; fileRef = 788F1CBB5056854EA4EC803C /* nacl_subprocess.cc */; }; + 5FC315C4AE4DFD18B5044507 /* libplatform_qual_lib.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 658DF7406F8E2CC4C6B06B12 /* libplatform_qual_lib.a */; }; + 638089A95B62BBE161E29F64 /* libstdc++.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 531F0D52DAD06B2FDD47E3F0 /* libstdc++.dylib */; }; + 684E8B606C84A886C39B1125 /* array_ppapi.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3872A50EC56C22316756B973 /* array_ppapi.cc */; }; + 690F26D86A72212115885EED /* libnacl_error_code.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 013A09905C1616D976A757AF /* libnacl_error_code.a */; }; + 6B243D4AC85849148127E03A /* libplatform.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42EE60AD403DC154C5EC61F9 /* libplatform.a */; }; + 6FFE26B7A4CBA83AD0BCFFF5 /* pnacl_coordinator.cc in Sources */ = {isa = PBXBuildFile; fileRef = E69FE285F97604FAE11454B0 /* pnacl_coordinator.cc */; }; + 7368FE8E6FDF9259C0BDD971 /* libimc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 706C0CEBAC386E6BE3A98295 /* libimc.a */; }; + 8CF13462509CA483E993B92F /* libsimple_service.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E91B2901EE15F2F2C7088CB6 /* libsimple_service.a */; }; + 9086771531DDBA7130CC11B3 /* var_utils.cc in Sources */ = {isa = PBXBuildFile; fileRef = F650DB81C3CF7F34006A6BAD /* var_utils.cc */; }; + A16831219B59A32A9C226811 /* libnacl_base.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E96903D51E8DF59322758354 /* libnacl_base.a */; }; + A4601E7CD4A6ECCFCF91EBF0 /* plugin.cc in Sources */ = {isa = PBXBuildFile; fileRef = CB2A206CD2DBA04E311BD1EA /* plugin.cc */; }; + B98B14C8345AEEBA3A45CB4F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F03AF2EE1E72EC3074410446 /* Foundation.framework */; }; + BFF3632C5EB24BE9670698FE /* srpc_client.cc in Sources */ = {isa = PBXBuildFile; fileRef = F76F549DCFA409BEE55D4C95 /* srpc_client.cc */; }; + C2A77F9E13B2E1F54C90C15A /* libncval_base_x86_32.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2F0AAB26024B850346F6F0 /* libncval_base_x86_32.a */; }; + C5D0D2048A09F2A59F4967C1 /* file_downloader.cc in Sources */ = {isa = PBXBuildFile; fileRef = 97EF6F302F3F341C605971D9 /* file_downloader.cc */; }; + C8023FD31DB9E1381D60A7EA /* browser_interface.cc in Sources */ = {isa = PBXBuildFile; fileRef = B4E363756B53E65AF47216E7 /* browser_interface.cc */; }; + D2D8713C4B46AB26971755AF /* utility.cc in Sources */ = {isa = PBXBuildFile; fileRef = E522B9A05A2A96FD713AA661 /* utility.cc */; }; + D6CC88F85B9322FE6E873D1F /* libppapi_cpp_objects_nacl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3ED014D1F4DDE993C5EF4E58 /* libppapi_cpp_objects_nacl.a */; }; + D976F0D7A3918E41AB897F8B /* libenv_cleanser.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A509464B57A0C2C731F1BC4 /* libenv_cleanser.a */; }; + DB78D658ACC668638C40C7AC /* libcrypto.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DEC45DDEC989898EC114A76 /* libcrypto.dylib */; }; + DBA0A1398CD359E6D36DB6C1 /* libnrd_xfer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1359B99AD1A47C20C520CEDA /* libnrd_xfer.a */; }; + E2D418C48F4925B014FD747F /* service_runtime.cc in Sources */ = {isa = PBXBuildFile; fileRef = A59CD9429D7A6DE16DFBCA32 /* service_runtime.cc */; }; + E3C1D974FB3C832CF13B71D1 /* libweak_ref.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 794ED711B227F03DB8BBFDA0 /* libweak_ref.a */; }; + E7912F04B6C454659C8E8B31 /* libgio_wrapped_desc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C94B65AAEE4ECF2881F037E1 /* libgio_wrapped_desc.a */; }; + E8F2F256824FFE15665322CB /* libnonnacl_util.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 571DAC5F0C0909F5CEB41616 /* libnonnacl_util.a */; }; + E9D03D9B1CD556AA475B44FC /* libgio.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 14E7A920987E4F1FE95D48D5 /* libgio.a */; }; + EB6BB43CDA6E40BFD2D22D13 /* nexe_arch.cc in Sources */ = {isa = PBXBuildFile; fileRef = 5CD4986240DE27123CBDB6D8 /* nexe_arch.cc */; }; + F712E4A778E070E02B0ECFCD /* module_ppapi.cc in Sources */ = {isa = PBXBuildFile; fileRef = B98DE0E3CA252C2A8E702D94 /* module_ppapi.cc */; }; + FFD5355ED935CD0CE1DB0DC9 /* sandbox_isa.cc in Sources */ = {isa = PBXBuildFile; fileRef = D72CEA0CD3FDE59EC74A6F8B /* sandbox_isa.cc */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 0003B8B7276FC14F0DC477DA /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = B2FB7677253523A0A25A08B0 /* platform.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 6EDCA4CFF96EFF980259120B; + remoteInfo = platform; + }; + 0114BE6B01C2BFCBFFA9C7E6 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E971B7E46E4DE6ADACA430E9 /* imc.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 052E2DCE6A6495174A6AF823; + remoteInfo = imc; + }; + 04F0C841FE19664D21A4D0A9 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = B2FB7677253523A0A25A08B0 /* platform.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = C90E55DA097368C583BD245B; + remoteInfo = platform_tests; + }; + 0758F97530AEDE3CE67BB0A6 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 71263C5E4C0ABD0899F08256 /* ppapi.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = E2F2A0E55B110BD510823436; + remoteInfo = ppapi_cpp_nacl; + }; + 089719F9643AC0FF948932C9 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BA93ECA3102254944047B24E /* reverse_service.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 9B769190C4EB567BFBE3F874; + remoteInfo = reverse_service; + }; + 0AEC5EFF2D70143384D1636B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 05D8A5556D0DDA00FDDA9514 /* service_runtime.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = C6F9CB4007FC3B928D32A804; + remoteInfo = env_cleanser; + }; + 1132810898F6AB98B15ADA8F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D4112F1C9780E6BEC6865D9D /* desc.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 91187F631935BEBB3350F24D; + remoteInfo = nrd_xfer; + }; + 1C1D6C98B18B424CF1378433 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F1A22203D8ED7C2018551F88 /* srpc.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 156230E7D439BA561B258646; + remoteInfo = nonnacl_srpc; + }; + 25D3D123657B8F815F6EDCB2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 71263C5E4C0ABD0899F08256 /* ppapi.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 0C68FB996E598DF8FB52A61D; + remoteInfo = ppapi_cpp_objects_nacl; + }; + 314B24CECA017C050099B1B5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 05D8A5556D0DDA00FDDA9514 /* service_runtime.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 3F189536128C41D1B6CE47F7; + remoteInfo = nacl_error_code; + }; + 3162E403391EA6C55C8F9E2F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CE1473CD1C8A3550D5651652 /* threading.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 4A148E304BDE0ACD656CE468; + remoteInfo = thread_interface; + }; + 3238117537ECAAEEF7DFF138 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F3D1E23996847B82084F8515 /* gio_wrapped_desc.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 6C3D1EC496E178FA7F77A82A; + remoteInfo = gio_wrapped_desc; + }; + 419F90ED0E5E7810F9716BDE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0A6EAB45210C88C01E62FDDF /* nonnacl_util.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 7F32C9B4D905A7091981B01D; + remoteInfo = sel_ldr_launcher; + }; + 42CC12B00D9312D6274C076C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E971B7E46E4DE6ADACA430E9 /* imc.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = CE0D104B94500F372D28F8A0; + remoteInfo = imc; + }; + 4867A7A2EA584A3D2CEBDBF5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = B2FB7677253523A0A25A08B0 /* platform.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 7EBB58F2B4C1E773852C6944; + remoteInfo = platform; + }; + 4A939CB2AC4C203830F317A1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = A0ADFEDFCBD2C14AE1E83C43 /* gio.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 1C2FFAB41620A7921D178BF8; + remoteInfo = gio; + }; + 4B74B54A09CAED68F32D53F8 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 237CD794767B28B3473FB65C /* nacl_base.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 2C292E0C6B382CCCCACC5A49; + remoteInfo = nacl_base; + }; + 57EAAAA3D2C25E8B173C5BBA /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 75D2380F7A757C5E3E8D4B99 /* weak_ref.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = E6F4821F5A736A9B7103604A; + remoteInfo = weak_ref; + }; + 58F04AB25BE810B74E971FF2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E3691F8BAE590283A630FA37 /* simple_service.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 68AFC284A0AC617185152B0F; + remoteInfo = simple_service; + }; + 62725EBBCE5EE777BAEAE894 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0FBFBF2DCCEDCC331F2877A2 /* validate_x86.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 6D768F682E2B602DC92E7821; + remoteInfo = ncval_base_verbose_x86_32; + }; + 63A285CE316A9D4BCC1738BC /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 71263C5E4C0ABD0899F08256 /* ppapi.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = E8A6179E550C8FBBA6FE4E48; + remoteInfo = ppapi_cpp_nacl; + }; + 66147BBC43F54931DB75356D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D4112F1C9780E6BEC6865D9D /* desc.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = DFF44C414C34422983F7CBD8; + remoteInfo = nrd_xfer; + }; + 6652B52D613CB70281D019B4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 75D2380F7A757C5E3E8D4B99 /* weak_ref.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 8EDF18EE675DD282A1BC6968; + remoteInfo = weak_ref; + }; + 6F53DA97D18BB12A13D88646 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0A6EAB45210C88C01E62FDDF /* nonnacl_util.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 034F7BF8B97E70DFE656DB0A; + remoteInfo = nonnacl_util; + }; + 730EC8CEAFE82A9644E1834E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = A0ADFEDFCBD2C14AE1E83C43 /* gio.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 00060C671039317748C5EBEB; + remoteInfo = gio; + }; + 8125F53552AC6BAA042754A0 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 237CD794767B28B3473FB65C /* nacl_base.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 12B50AA4E728E7C47CF24683; + remoteInfo = nacl_base; + }; + 8254E37C37900676817DF9CE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 05D8A5556D0DDA00FDDA9514 /* service_runtime.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 8AF7939C3267891763B02F69; + remoteInfo = env_cleanser; + }; + 8C7E05F51C34F5F463277CAB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E3691F8BAE590283A630FA37 /* simple_service.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 0EF0AC33A3851614B81964D5; + remoteInfo = simple_service; + }; + 8EDCFFBB3BF791E2B675F8F8 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = AE544ECA45F1A5014DACE107 /* platform_qualify.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 6D8B830DD6C4A436403F8EA5; + remoteInfo = platform_qual_lib; + }; + 916A6F17D2A13C2ED4B2A21A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8F4EE08CED8464B651711EAB /* ppapi_proxy.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = A69A7B7DC20908928BE34654; + remoteInfo = nacl_ppapi_browser; + }; + 96E959948F294CC1864028C3 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0A6EAB45210C88C01E62FDDF /* nonnacl_util.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = D15D02E0D100CCC652A8DD92; + remoteInfo = sel_ldr_launcher; + }; + 983A03E485D1C4A89CE090B4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0FBFBF2DCCEDCC331F2877A2 /* validate_x86.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = F16F7002D3CD31B0B71D6CB9; + remoteInfo = ncval_base_x86_32; + }; + 9CC5DA808C751EBA1C8143B3 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E806BEDA5E62B16521327F9F /* jsoncpp.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = A5BFECDBEB4797D8B5F73D4B; + remoteInfo = jsoncpp; + }; + 9F3BB1F9C97CD27201E909E1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8F4EE08CED8464B651711EAB /* ppapi_proxy.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 8346DD1517DC2BED1C8129D4; + remoteInfo = nacl_ppapi_browser; + }; + A199E645CD2A3BE4709F9A23 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0A6EAB45210C88C01E62FDDF /* nonnacl_util.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 9CC0194EB44B35E80F06C062; + remoteInfo = nonnacl_util; + }; + A574CADB32986B354614D7B0 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BA93ECA3102254944047B24E /* reverse_service.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 112978558DA53FE84321A3FC; + remoteInfo = reverse_service; + }; + B68583BCB94CBB489A1426AD /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E806BEDA5E62B16521327F9F /* jsoncpp.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 4800408075CA8E86E9CDB180; + remoteInfo = jsoncpp; + }; + C9BCE56D5A51DC439B457B39 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 05D8A5556D0DDA00FDDA9514 /* service_runtime.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = A27137A2D7A0AE496EF576E3; + remoteInfo = nacl_error_code; + }; + CA8D5469D031247677077766 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CE1473CD1C8A3550D5651652 /* threading.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 52573AAB45B43549B82F623B; + remoteInfo = thread_interface; + }; + CB2994AD5EAFAED788327646 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0FBFBF2DCCEDCC331F2877A2 /* validate_x86.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 8EACDEF34EABF2BAC5F9688F; + remoteInfo = ncval_base_x86_32; + }; + CF908E2F4A70D4D9487AF27E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 71263C5E4C0ABD0899F08256 /* ppapi.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 0D055E483800A7A2D370FE96; + remoteInfo = ppapi_cpp_objects_nacl; + }; + D50B799992542568C332CA0A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 05D8A5556D0DDA00FDDA9514 /* service_runtime.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 7005276B56BA271E1BC46F42; + remoteInfo = sel; + }; + D5BB90F42A361F02BA2C52C9 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 05D8A5556D0DDA00FDDA9514 /* service_runtime.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = A610A6A16A498AB4FE70F080; + remoteInfo = sel_ldr; + }; + D95F9F60774B2A054A3E97A3 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 05D8A5556D0DDA00FDDA9514 /* service_runtime.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 1DE0B82B2F96C86E55863C01; + remoteInfo = nacl_xdr; + }; + DD4C0983CC83FA9D9C057750 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F3D1E23996847B82084F8515 /* gio_wrapped_desc.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 2342F285F9684439F77D7C05; + remoteInfo = gio_wrapped_desc; + }; + DF719A069E0ABC9276F9EEAF /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 05D8A5556D0DDA00FDDA9514 /* service_runtime.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 8026BC40E941F4AF6FEA321A; + remoteInfo = container; + }; + E3AFD96A10B83D4ABAE4ABD4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F1A22203D8ED7C2018551F88 /* srpc.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 1CF883829F3246950ED408F4; + remoteInfo = nonnacl_srpc; + }; + E8295B85A41710C432250776 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E971B7E46E4DE6ADACA430E9 /* imc.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 8BFDD35612BDC164F2AC533B; + remoteInfo = sigpipe_test; + }; + F2BFC9E78E3A275281FAEB7D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = AE544ECA45F1A5014DACE107 /* platform_qualify.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 2DBE41AA94FC9751D7CE6F75; + remoteInfo = platform_qual_lib; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 0305144425480087921B6154 /* external_code.gypi */ = {isa = PBXFileReference; lastKnownFileType = text; name = external_code.gypi; path = ../../../build/external_code.gypi; sourceTree = "<group>"; }; + 054122D1AE4E27A7A2B6204B /* method_map.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = method_map.cc; sourceTree = "<group>"; }; + 05D8A5556D0DDA00FDDA9514 /* service_runtime.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = service_runtime.xcodeproj; path = ../service_runtime/service_runtime.xcodeproj; sourceTree = SOURCE_ROOT; }; + 0A6EAB45210C88C01E62FDDF /* nonnacl_util.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = nonnacl_util.xcodeproj; path = ../nonnacl_util/nonnacl_util.xcodeproj; sourceTree = SOURCE_ROOT; }; + 0FBFBF2DCCEDCC331F2877A2 /* validate_x86.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = validate_x86.xcodeproj; path = ../validator/x86/validate_x86.xcodeproj; sourceTree = SOURCE_ROOT; }; + 237CD794767B28B3473FB65C /* nacl_base.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = nacl_base.xcodeproj; path = ../nacl_base/nacl_base.xcodeproj; sourceTree = SOURCE_ROOT; }; + 2FA4ECBA9BFD0DFFF24F01EF /* scriptable_handle.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = scriptable_handle.cc; sourceTree = "<group>"; }; + 3872A50EC56C22316756B973 /* array_ppapi.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = array_ppapi.cc; sourceTree = "<group>"; }; + 531F0D52DAD06B2FDD47E3F0 /* libstdc++.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libstdc++.dylib"; path = "usr/lib/libstdc++.dylib"; sourceTree = SDKROOT; }; + 5556F891DFC4BEB5F873DF4D /* common.gypi */ = {isa = PBXFileReference; lastKnownFileType = text; name = common.gypi; path = ../../../build/common.gypi; sourceTree = "<group>"; }; + 59CF0E40FFA63F3D6B56C5DC /* plugin.gyp */ = {isa = PBXFileReference; lastKnownFileType = text; path = plugin.gyp; sourceTree = "<group>"; }; + 5CD4986240DE27123CBDB6D8 /* nexe_arch.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = nexe_arch.cc; sourceTree = "<group>"; }; + 664706E5C1B8DC1ED366607A /* libppGoogleNaClPlugin.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libppGoogleNaClPlugin.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; + 6840E9858FC08BB95EE1F006 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; }; + 71263C5E4C0ABD0899F08256 /* ppapi.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ppapi.xcodeproj; path = ../../shared/ppapi/ppapi.xcodeproj; sourceTree = SOURCE_ROOT; }; + 75D2380F7A757C5E3E8D4B99 /* weak_ref.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = weak_ref.xcodeproj; path = ../weak_ref/weak_ref.xcodeproj; sourceTree = SOURCE_ROOT; }; + 788F1CBB5056854EA4EC803C /* nacl_subprocess.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = nacl_subprocess.cc; sourceTree = "<group>"; }; + 8DEC45DDEC989898EC114A76 /* libcrypto.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libcrypto.dylib; path = usr/lib/libcrypto.dylib; sourceTree = SDKROOT; }; + 8F4EE08CED8464B651711EAB /* ppapi_proxy.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ppapi_proxy.xcodeproj; path = ../../../../ppapi/native_client/src/shared/ppapi_proxy/ppapi_proxy.xcodeproj; sourceTree = SOURCE_ROOT; }; + 97EF6F302F3F341C605971D9 /* file_downloader.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = file_downloader.cc; sourceTree = "<group>"; }; + A0ADFEDFCBD2C14AE1E83C43 /* gio.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = gio.xcodeproj; path = ../../shared/gio/gio.xcodeproj; sourceTree = SOURCE_ROOT; }; + A59CD9429D7A6DE16DFBCA32 /* service_runtime.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = service_runtime.cc; sourceTree = "<group>"; }; + AE544ECA45F1A5014DACE107 /* platform_qualify.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = platform_qualify.xcodeproj; path = ../platform_qualify/platform_qualify.xcodeproj; sourceTree = SOURCE_ROOT; }; + B2FB7677253523A0A25A08B0 /* platform.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = platform.xcodeproj; path = ../../shared/platform/platform.xcodeproj; sourceTree = SOURCE_ROOT; }; + B4E363756B53E65AF47216E7 /* browser_interface.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = browser_interface.cc; sourceTree = "<group>"; }; + B98DE0E3CA252C2A8E702D94 /* module_ppapi.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = module_ppapi.cc; sourceTree = "<group>"; }; + BA633570BC84E88A5485D7F7 /* libssl.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libssl.dylib; path = usr/lib/libssl.dylib; sourceTree = SDKROOT; }; + BA93ECA3102254944047B24E /* reverse_service.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = reverse_service.xcodeproj; path = ../reverse_service/reverse_service.xcodeproj; sourceTree = SOURCE_ROOT; }; + C39DC96319E734E57E62E3EB /* pnacl_srpc_lib.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = pnacl_srpc_lib.cc; sourceTree = "<group>"; }; + CB2A206CD2DBA04E311BD1EA /* plugin.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = plugin.cc; sourceTree = "<group>"; }; + CE1473CD1C8A3550D5651652 /* threading.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = threading.xcodeproj; path = ../threading/threading.xcodeproj; sourceTree = SOURCE_ROOT; }; + D33D7B4AB1DE8A51FD613307 /* manifest.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = manifest.cc; sourceTree = "<group>"; }; + D4112F1C9780E6BEC6865D9D /* desc.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = desc.xcodeproj; path = ../desc/desc.xcodeproj; sourceTree = SOURCE_ROOT; }; + D72CEA0CD3FDE59EC74A6F8B /* sandbox_isa.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = sandbox_isa.cc; sourceTree = "<group>"; }; + E3691F8BAE590283A630FA37 /* simple_service.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = simple_service.xcodeproj; path = ../simple_service/simple_service.xcodeproj; sourceTree = SOURCE_ROOT; }; + E522B9A05A2A96FD713AA661 /* utility.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = utility.cc; sourceTree = "<group>"; }; + E69FE285F97604FAE11454B0 /* pnacl_coordinator.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = pnacl_coordinator.cc; sourceTree = "<group>"; }; + E806BEDA5E62B16521327F9F /* jsoncpp.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = jsoncpp.xcodeproj; path = ../../third_party_mod/jsoncpp/jsoncpp.xcodeproj; sourceTree = SOURCE_ROOT; }; + E971B7E46E4DE6ADACA430E9 /* imc.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = imc.xcodeproj; path = ../../shared/imc/imc.xcodeproj; sourceTree = SOURCE_ROOT; }; + EE9D2B679C77B23EFC7E9AAB /* plugin.gypi */ = {isa = PBXFileReference; lastKnownFileType = text; path = plugin.gypi; sourceTree = "<group>"; }; + F03AF2EE1E72EC3074410446 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + F1A22203D8ED7C2018551F88 /* srpc.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = srpc.xcodeproj; path = ../../shared/srpc/srpc.xcodeproj; sourceTree = SOURCE_ROOT; }; + F3D1E23996847B82084F8515 /* gio_wrapped_desc.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = gio_wrapped_desc.xcodeproj; path = ../gio/gio_wrapped_desc.xcodeproj; sourceTree = SOURCE_ROOT; }; + F4AD44658ADACBA1AE1C58EB /* desc_based_handle.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = desc_based_handle.cc; sourceTree = "<group>"; }; + F650DB81C3CF7F34006A6BAD /* var_utils.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = var_utils.cc; sourceTree = "<group>"; }; + F6CEFA6C5EF47C924C602649 /* string_encoding.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = string_encoding.cc; sourceTree = "<group>"; }; + F76F549DCFA409BEE55D4C95 /* srpc_client.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = srpc_client.cc; sourceTree = "<group>"; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + EBD10901A168BF9C87632072 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + E9D03D9B1CD556AA475B44FC /* libgio.a in Frameworks */, + 7368FE8E6FDF9259C0BDD971 /* libimc.a in Frameworks */, + 6B243D4AC85849148127E03A /* libplatform.a in Frameworks */, + 35E0F7AF811CD3E0FFD3E727 /* libppapi_cpp_nacl.a in Frameworks */, + 4FD2B9E03C6000C497DA4238 /* libnacl_ppapi_browser.a in Frameworks */, + 0512B675305D3AFD29700B0A /* libnonnacl_srpc.a in Frameworks */, + 50C6C683F64E64D75FDB6A63 /* libjsoncpp.a in Frameworks */, + DBA0A1398CD359E6D36DB6C1 /* libnrd_xfer.a in Frameworks */, + E8F2F256824FFE15665322CB /* libnonnacl_util.a in Frameworks */, + 5FC315C4AE4DFD18B5044507 /* libplatform_qual_lib.a in Frameworks */, + E7912F04B6C454659C8E8B31 /* libgio_wrapped_desc.a in Frameworks */, + 8CF13462509CA483E993B92F /* libsimple_service.a in Frameworks */, + 40FD08307E5A8D1798048FEF /* libreverse_service.a in Frameworks */, + E3C1D974FB3C832CF13B71D1 /* libweak_ref.a in Frameworks */, + D6CC88F85B9322FE6E873D1F /* libppapi_cpp_objects_nacl.a in Frameworks */, + A16831219B59A32A9C226811 /* libnacl_base.a in Frameworks */, + 593D357067E80D83F90273A2 /* libsel_ldr_launcher.a in Frameworks */, + D976F0D7A3918E41AB897F8B /* libenv_cleanser.a in Frameworks */, + 690F26D86A72212115885EED /* libnacl_error_code.a in Frameworks */, + C2A77F9E13B2E1F54C90C15A /* libncval_base_x86_32.a in Frameworks */, + 503165674E302823FC6DBE86 /* libthread_interface.a in Frameworks */, + 23254754DEFBBDEA139453B4 /* Carbon.framework in Frameworks */, + DB78D658ACC668638C40C7AC /* libcrypto.dylib in Frameworks */, + 1FE2ACF356B68E5995EC8757 /* libssl.dylib in Frameworks */, + 638089A95B62BBE161E29F64 /* libstdc++.dylib in Frameworks */, + B98B14C8345AEEBA3A45CB4F /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 15A8E33ABC57C888DDD4277A /* Products */ = { + isa = PBXGroup; + children = ( + E96903D51E8DF59322758354 /* libnacl_base.a */, + ); + name = Products; + sourceTree = "<group>"; + }; + 1927C2A75944AEC85B22F012 /* Products */ = { + isa = PBXGroup; + children = ( + 706C0CEBAC386E6BE3A98295 /* libimc.a */, + 5C4041FA06F9D6756796313F /* sigpipe_test */, + ); + name = Products; + sourceTree = "<group>"; + }; + 26CC7167447280390E8A3EF3 /* Products */ = { + isa = PBXGroup; + children = ( + 664706E5C1B8DC1ED366607A /* libppGoogleNaClPlugin.dylib */, + ); + name = Products; + sourceTree = "<group>"; + }; + 2B64C4DDB8592234918691DF /* Products */ = { + isa = PBXGroup; + children = ( + E91B2901EE15F2F2C7088CB6 /* libsimple_service.a */, + ); + name = Products; + sourceTree = "<group>"; + }; + 30CBEF79B9B2257909C1D16B /* Products */ = { + isa = PBXGroup; + children = ( + C0C6572D3103B89B48D63313 /* libnonnacl_srpc.a */, + ); + name = Products; + sourceTree = "<group>"; + }; + 30F3D41C862094914C3539EA /* Products */ = { + isa = PBXGroup; + children = ( + 5CB4A8509FD7B34E5A1AFF6F /* libjsoncpp.a */, + ); + name = Products; + sourceTree = "<group>"; + }; + 30FA3664B5061BEA4E3846FB /* Products */ = { + isa = PBXGroup; + children = ( + DC6D23D35097F45E8EDB69E5 /* libnacl_ppapi_browser.a */, + ); + name = Products; + sourceTree = "<group>"; + }; + 45FC264A621FB4D5D8434C30 /* arch_x86 */ = { + isa = PBXGroup; + children = ( + D72CEA0CD3FDE59EC74A6F8B /* sandbox_isa.cc */, + ); + path = arch_x86; + sourceTree = "<group>"; + }; + 57B0612AD487EDC43569812F /* Products */ = { + isa = PBXGroup; + children = ( + 14E7A920987E4F1FE95D48D5 /* libgio.a */, + ); + name = Products; + sourceTree = "<group>"; + }; + 64D348CF77C5F10CD34F3519 /* Build */ = { + isa = PBXGroup; + children = ( + 5556F891DFC4BEB5F873DF4D /* common.gypi */, + 0305144425480087921B6154 /* external_code.gypi */, + 59CF0E40FFA63F3D6B56C5DC /* plugin.gyp */, + EE9D2B679C77B23EFC7E9AAB /* plugin.gypi */, + ); + name = Build; + sourceTree = "<group>"; + }; + 6A18885A01F8BD5D745F2ED3 /* Products */ = { + isa = PBXGroup; + children = ( + C94B65AAEE4ECF2881F037E1 /* libgio_wrapped_desc.a */, + ); + name = Products; + sourceTree = "<group>"; + }; + 7290F1BD04FF55BAE7141EBB /* Products */ = { + isa = PBXGroup; + children = ( + B5543B004A4EF5E566475138 /* libreverse_service.a */, + ); + name = Products; + sourceTree = "<group>"; + }; + 75858ACFFD509AFB313E8543 /* Products */ = { + isa = PBXGroup; + children = ( + 89A2C5EF51849A55FE917FAB /* libsel.a */, + BCCAC1A96D8E0588BC6B4BBB /* libcontainer.a */, + ABA8815426C50752ABC1DBED /* libnacl_xdr.a */, + 013A09905C1616D976A757AF /* libnacl_error_code.a */, + 4A509464B57A0C2C731F1BC4 /* libenv_cleanser.a */, + 61FC5CC82A8604D4E4886FCA /* sel_ldr */, + ); + name = Products; + sourceTree = "<group>"; + }; + 7FF733352998067F8D52D82B /* Products */ = { + isa = PBXGroup; + children = ( + 794ED711B227F03DB8BBFDA0 /* libweak_ref.a */, + ); + name = Products; + sourceTree = "<group>"; + }; + 84CE719694CC990CB84C50ED /* Frameworks */ = { + isa = PBXGroup; + children = ( + 6840E9858FC08BB95EE1F006 /* Carbon.framework */, + F03AF2EE1E72EC3074410446 /* Foundation.framework */, + 8DEC45DDEC989898EC114A76 /* libcrypto.dylib */, + BA633570BC84E88A5485D7F7 /* libssl.dylib */, + 531F0D52DAD06B2FDD47E3F0 /* libstdc++.dylib */, + ); + name = Frameworks; + sourceTree = "<group>"; + }; + 89C6C604CF17E42F330E86A5 /* Products */ = { + isa = PBXGroup; + children = ( + 42EE60AD403DC154C5EC61F9 /* libplatform.a */, + 15ADAFADB6DF7D5B2C2F6A80 /* platform_tests */, + ); + name = Products; + sourceTree = "<group>"; + }; + 9DC1B5402058106C439B81C6 = { + isa = PBXGroup; + children = ( + E806FA5102ABEE32BF5612CB /* Source */, + BF36DAB8486E3EF002C36DA9 /* Projects */, + 84CE719694CC990CB84C50ED /* Frameworks */, + 26CC7167447280390E8A3EF3 /* Products */, + 64D348CF77C5F10CD34F3519 /* Build */, + ); + sourceTree = "<group>"; + }; + BD810EB0A148CA7826A2E76F /* Products */ = { + isa = PBXGroup; + children = ( + D120F91621BE6927B701B8F6 /* libthread_interface.a */, + ); + name = Products; + sourceTree = "<group>"; + }; + BF36DAB8486E3EF002C36DA9 /* Projects */ = { + isa = PBXGroup; + children = ( + D4112F1C9780E6BEC6865D9D /* desc.xcodeproj */, + A0ADFEDFCBD2C14AE1E83C43 /* gio.xcodeproj */, + F3D1E23996847B82084F8515 /* gio_wrapped_desc.xcodeproj */, + E971B7E46E4DE6ADACA430E9 /* imc.xcodeproj */, + E806BEDA5E62B16521327F9F /* jsoncpp.xcodeproj */, + 237CD794767B28B3473FB65C /* nacl_base.xcodeproj */, + 0A6EAB45210C88C01E62FDDF /* nonnacl_util.xcodeproj */, + B2FB7677253523A0A25A08B0 /* platform.xcodeproj */, + AE544ECA45F1A5014DACE107 /* platform_qualify.xcodeproj */, + 71263C5E4C0ABD0899F08256 /* ppapi.xcodeproj */, + 8F4EE08CED8464B651711EAB /* ppapi_proxy.xcodeproj */, + BA93ECA3102254944047B24E /* reverse_service.xcodeproj */, + 05D8A5556D0DDA00FDDA9514 /* service_runtime.xcodeproj */, + E3691F8BAE590283A630FA37 /* simple_service.xcodeproj */, + F1A22203D8ED7C2018551F88 /* srpc.xcodeproj */, + CE1473CD1C8A3550D5651652 /* threading.xcodeproj */, + 0FBFBF2DCCEDCC331F2877A2 /* validate_x86.xcodeproj */, + 75D2380F7A757C5E3E8D4B99 /* weak_ref.xcodeproj */, + ); + name = Projects; + sourceTree = "<group>"; + }; + C32925566E196C99C0EA974B /* Products */ = { + isa = PBXGroup; + children = ( + 1359B99AD1A47C20C520CEDA /* libnrd_xfer.a */, + ); + name = Products; + sourceTree = "<group>"; + }; + C763A0DFB97513D1541CD060 /* Products */ = { + isa = PBXGroup; + children = ( + A17B539C4A2EA1E34EC86B94 /* libsel_ldr_launcher.a */, + 571DAC5F0C0909F5CEB41616 /* libnonnacl_util.a */, + ); + name = Products; + sourceTree = "<group>"; + }; + CC091081913EAE1EEE5FBB17 /* Products */ = { + isa = PBXGroup; + children = ( + 3ED014D1F4DDE993C5EF4E58 /* libppapi_cpp_objects_nacl.a */, + D8B1B1193623AF3C786449A3 /* libppapi_cpp_nacl.a */, + ); + name = Products; + sourceTree = "<group>"; + }; + D3C77E09710980B1D09F0914 /* Products */ = { + isa = PBXGroup; + children = ( + 658DF7406F8E2CC4C6B06B12 /* libplatform_qual_lib.a */, + ); + name = Products; + sourceTree = "<group>"; + }; + E806FA5102ABEE32BF5612CB /* Source */ = { + isa = PBXGroup; + children = ( + 45FC264A621FB4D5D8434C30 /* arch_x86 */, + 3872A50EC56C22316756B973 /* array_ppapi.cc */, + B4E363756B53E65AF47216E7 /* browser_interface.cc */, + F4AD44658ADACBA1AE1C58EB /* desc_based_handle.cc */, + 97EF6F302F3F341C605971D9 /* file_downloader.cc */, + D33D7B4AB1DE8A51FD613307 /* manifest.cc */, + 054122D1AE4E27A7A2B6204B /* method_map.cc */, + B98DE0E3CA252C2A8E702D94 /* module_ppapi.cc */, + 788F1CBB5056854EA4EC803C /* nacl_subprocess.cc */, + 5CD4986240DE27123CBDB6D8 /* nexe_arch.cc */, + CB2A206CD2DBA04E311BD1EA /* plugin.cc */, + E69FE285F97604FAE11454B0 /* pnacl_coordinator.cc */, + C39DC96319E734E57E62E3EB /* pnacl_srpc_lib.cc */, + 2FA4ECBA9BFD0DFFF24F01EF /* scriptable_handle.cc */, + A59CD9429D7A6DE16DFBCA32 /* service_runtime.cc */, + F76F549DCFA409BEE55D4C95 /* srpc_client.cc */, + F6CEFA6C5EF47C924C602649 /* string_encoding.cc */, + E522B9A05A2A96FD713AA661 /* utility.cc */, + F650DB81C3CF7F34006A6BAD /* var_utils.cc */, + ); + name = Source; + sourceTree = "<group>"; + }; + F401C863270455EF01D267D7 /* Products */ = { + isa = PBXGroup; + children = ( + 8B2F0AAB26024B850346F6F0 /* libncval_base_x86_32.a */, + B06B28E92774648E62A7A6AE /* libncval_base_verbose_x86_32.a */, + ); + name = Products; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 7FE9E83C876167A9F63F7F77 /* ppGoogleNaClPlugin */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8FBD68EA480C8DB4E7449C10 /* Build configuration list for PBXNativeTarget "ppGoogleNaClPlugin" */; + buildPhases = ( + B723BD2A25DF34CC35827295 /* Sources */, + EBD10901A168BF9C87632072 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 3675EF172F844DAFBFF0E2E2 /* PBXTargetDependency */, + 2C4B6AB54DCD38395A63D803 /* PBXTargetDependency */, + AD275474C45A66D5EC683D3F /* PBXTargetDependency */, + A1D3403AA9994F940C3E099D /* PBXTargetDependency */, + 994BC8BB87FBE94789E23A19 /* PBXTargetDependency */, + 9EE35712DD628F51DBF93B55 /* PBXTargetDependency */, + 0005E3D8CB9C2AE1CADEB22A /* PBXTargetDependency */, + 5B1485C5A32E287D1BF39EB2 /* PBXTargetDependency */, + FDC6C4CBE7A04145B9622D91 /* PBXTargetDependency */, + 7EFB31E6092DEC5CFA255855 /* PBXTargetDependency */, + 585A0DA820803E5184141F8B /* PBXTargetDependency */, + 3F98BC1B25AD8A573807D2AF /* PBXTargetDependency */, + A14332ED112A67B8972E2D4F /* PBXTargetDependency */, + 75E414F600163EBE9E2CBE02 /* PBXTargetDependency */, + BBAD497F2A54F9A7B52EDE7E /* PBXTargetDependency */, + 28A4CB124CA2B051657AEF2E /* PBXTargetDependency */, + A5DA07C8D2E83C4050B36C4E /* PBXTargetDependency */, + 7CB32C0F5C85F1DB70579D63 /* PBXTargetDependency */, + DC9B623BA9FB0CF747632F55 /* PBXTargetDependency */, + 407313FDBF41F51C9868F0BE /* PBXTargetDependency */, + C61FC17A1D5066D2EC8BFAD7 /* PBXTargetDependency */, + ); + name = ppGoogleNaClPlugin; + productName = ppGoogleNaClPlugin; + productReference = 664706E5C1B8DC1ED366607A /* libppGoogleNaClPlugin.dylib */; + productType = "com.apple.product-type.library.dynamic"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + E9BF4284A4D7602AA0864CA3 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + }; + buildConfigurationList = 0F67E6C4E63CA9C6E86EF43C /* Build configuration list for PBXProject "plugin" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + mainGroup = 9DC1B5402058106C439B81C6; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = C32925566E196C99C0EA974B /* Products */; + ProjectRef = D4112F1C9780E6BEC6865D9D /* desc.xcodeproj */; + }, + { + ProductGroup = 57B0612AD487EDC43569812F /* Products */; + ProjectRef = A0ADFEDFCBD2C14AE1E83C43 /* gio.xcodeproj */; + }, + { + ProductGroup = 6A18885A01F8BD5D745F2ED3 /* Products */; + ProjectRef = F3D1E23996847B82084F8515 /* gio_wrapped_desc.xcodeproj */; + }, + { + ProductGroup = 1927C2A75944AEC85B22F012 /* Products */; + ProjectRef = E971B7E46E4DE6ADACA430E9 /* imc.xcodeproj */; + }, + { + ProductGroup = 30F3D41C862094914C3539EA /* Products */; + ProjectRef = E806BEDA5E62B16521327F9F /* jsoncpp.xcodeproj */; + }, + { + ProductGroup = 15A8E33ABC57C888DDD4277A /* Products */; + ProjectRef = 237CD794767B28B3473FB65C /* nacl_base.xcodeproj */; + }, + { + ProductGroup = C763A0DFB97513D1541CD060 /* Products */; + ProjectRef = 0A6EAB45210C88C01E62FDDF /* nonnacl_util.xcodeproj */; + }, + { + ProductGroup = 89C6C604CF17E42F330E86A5 /* Products */; + ProjectRef = B2FB7677253523A0A25A08B0 /* platform.xcodeproj */; + }, + { + ProductGroup = D3C77E09710980B1D09F0914 /* Products */; + ProjectRef = AE544ECA45F1A5014DACE107 /* platform_qualify.xcodeproj */; + }, + { + ProductGroup = CC091081913EAE1EEE5FBB17 /* Products */; + ProjectRef = 71263C5E4C0ABD0899F08256 /* ppapi.xcodeproj */; + }, + { + ProductGroup = 30FA3664B5061BEA4E3846FB /* Products */; + ProjectRef = 8F4EE08CED8464B651711EAB /* ppapi_proxy.xcodeproj */; + }, + { + ProductGroup = 7290F1BD04FF55BAE7141EBB /* Products */; + ProjectRef = BA93ECA3102254944047B24E /* reverse_service.xcodeproj */; + }, + { + ProductGroup = 75858ACFFD509AFB313E8543 /* Products */; + ProjectRef = 05D8A5556D0DDA00FDDA9514 /* service_runtime.xcodeproj */; + }, + { + ProductGroup = 2B64C4DDB8592234918691DF /* Products */; + ProjectRef = E3691F8BAE590283A630FA37 /* simple_service.xcodeproj */; + }, + { + ProductGroup = 30CBEF79B9B2257909C1D16B /* Products */; + ProjectRef = F1A22203D8ED7C2018551F88 /* srpc.xcodeproj */; + }, + { + ProductGroup = BD810EB0A148CA7826A2E76F /* Products */; + ProjectRef = CE1473CD1C8A3550D5651652 /* threading.xcodeproj */; + }, + { + ProductGroup = F401C863270455EF01D267D7 /* Products */; + ProjectRef = 0FBFBF2DCCEDCC331F2877A2 /* validate_x86.xcodeproj */; + }, + { + ProductGroup = 7FF733352998067F8D52D82B /* Products */; + ProjectRef = 75D2380F7A757C5E3E8D4B99 /* weak_ref.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + 7FE9E83C876167A9F63F7F77 /* ppGoogleNaClPlugin */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + 013A09905C1616D976A757AF /* libnacl_error_code.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libnacl_error_code.a; + remoteRef = C9BCE56D5A51DC439B457B39 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 1359B99AD1A47C20C520CEDA /* libnrd_xfer.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libnrd_xfer.a; + remoteRef = 1132810898F6AB98B15ADA8F /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 14E7A920987E4F1FE95D48D5 /* libgio.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libgio.a; + remoteRef = 730EC8CEAFE82A9644E1834E /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 15ADAFADB6DF7D5B2C2F6A80 /* platform_tests */ = { + isa = PBXReferenceProxy; + fileType = "compiled.mach-o.executable"; + path = platform_tests; + remoteRef = 04F0C841FE19664D21A4D0A9 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 3ED014D1F4DDE993C5EF4E58 /* libppapi_cpp_objects_nacl.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libppapi_cpp_objects_nacl.a; + remoteRef = 25D3D123657B8F815F6EDCB2 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 42EE60AD403DC154C5EC61F9 /* libplatform.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libplatform.a; + remoteRef = 0003B8B7276FC14F0DC477DA /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 4A509464B57A0C2C731F1BC4 /* libenv_cleanser.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libenv_cleanser.a; + remoteRef = 8254E37C37900676817DF9CE /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 571DAC5F0C0909F5CEB41616 /* libnonnacl_util.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libnonnacl_util.a; + remoteRef = 6F53DA97D18BB12A13D88646 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 5C4041FA06F9D6756796313F /* sigpipe_test */ = { + isa = PBXReferenceProxy; + fileType = "compiled.mach-o.executable"; + path = sigpipe_test; + remoteRef = E8295B85A41710C432250776 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 5CB4A8509FD7B34E5A1AFF6F /* libjsoncpp.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libjsoncpp.a; + remoteRef = B68583BCB94CBB489A1426AD /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 61FC5CC82A8604D4E4886FCA /* sel_ldr */ = { + isa = PBXReferenceProxy; + fileType = "compiled.mach-o.executable"; + path = sel_ldr; + remoteRef = D5BB90F42A361F02BA2C52C9 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 658DF7406F8E2CC4C6B06B12 /* libplatform_qual_lib.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libplatform_qual_lib.a; + remoteRef = F2BFC9E78E3A275281FAEB7D /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 706C0CEBAC386E6BE3A98295 /* libimc.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libimc.a; + remoteRef = 42CC12B00D9312D6274C076C /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 794ED711B227F03DB8BBFDA0 /* libweak_ref.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libweak_ref.a; + remoteRef = 6652B52D613CB70281D019B4 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 89A2C5EF51849A55FE917FAB /* libsel.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libsel.a; + remoteRef = D50B799992542568C332CA0A /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 8B2F0AAB26024B850346F6F0 /* libncval_base_x86_32.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libncval_base_x86_32.a; + remoteRef = 983A03E485D1C4A89CE090B4 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + A17B539C4A2EA1E34EC86B94 /* libsel_ldr_launcher.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libsel_ldr_launcher.a; + remoteRef = 419F90ED0E5E7810F9716BDE /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + ABA8815426C50752ABC1DBED /* libnacl_xdr.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libnacl_xdr.a; + remoteRef = D95F9F60774B2A054A3E97A3 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + B06B28E92774648E62A7A6AE /* libncval_base_verbose_x86_32.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libncval_base_verbose_x86_32.a; + remoteRef = 62725EBBCE5EE777BAEAE894 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + B5543B004A4EF5E566475138 /* libreverse_service.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libreverse_service.a; + remoteRef = 089719F9643AC0FF948932C9 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + BCCAC1A96D8E0588BC6B4BBB /* libcontainer.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libcontainer.a; + remoteRef = DF719A069E0ABC9276F9EEAF /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + C0C6572D3103B89B48D63313 /* libnonnacl_srpc.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libnonnacl_srpc.a; + remoteRef = 1C1D6C98B18B424CF1378433 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + C94B65AAEE4ECF2881F037E1 /* libgio_wrapped_desc.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libgio_wrapped_desc.a; + remoteRef = DD4C0983CC83FA9D9C057750 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + D120F91621BE6927B701B8F6 /* libthread_interface.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libthread_interface.a; + remoteRef = CA8D5469D031247677077766 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + D8B1B1193623AF3C786449A3 /* libppapi_cpp_nacl.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libppapi_cpp_nacl.a; + remoteRef = 63A285CE316A9D4BCC1738BC /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + DC6D23D35097F45E8EDB69E5 /* libnacl_ppapi_browser.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libnacl_ppapi_browser.a; + remoteRef = 9F3BB1F9C97CD27201E909E1 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + E91B2901EE15F2F2C7088CB6 /* libsimple_service.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libsimple_service.a; + remoteRef = 8C7E05F51C34F5F463277CAB /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + E96903D51E8DF59322758354 /* libnacl_base.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libnacl_base.a; + remoteRef = 4B74B54A09CAED68F32D53F8 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXSourcesBuildPhase section */ + B723BD2A25DF34CC35827295 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 684E8B606C84A886C39B1125 /* array_ppapi.cc in Sources */, + C8023FD31DB9E1381D60A7EA /* browser_interface.cc in Sources */, + 5446AC3AFDBDEA2E886FCE38 /* desc_based_handle.cc in Sources */, + C5D0D2048A09F2A59F4967C1 /* file_downloader.cc in Sources */, + 2F4A1B21FBEC65F36E0CB2E7 /* manifest.cc in Sources */, + 51ED36800220F9928F8BA8D5 /* method_map.cc in Sources */, + F712E4A778E070E02B0ECFCD /* module_ppapi.cc in Sources */, + 5DDFB212A1B5455284BDB727 /* nacl_subprocess.cc in Sources */, + EB6BB43CDA6E40BFD2D22D13 /* nexe_arch.cc in Sources */, + A4601E7CD4A6ECCFCF91EBF0 /* plugin.cc in Sources */, + 6FFE26B7A4CBA83AD0BCFFF5 /* pnacl_coordinator.cc in Sources */, + 49F0DB4042A7635BED7A3875 /* pnacl_srpc_lib.cc in Sources */, + 4A53FCC57ED22D39B86D6E00 /* scriptable_handle.cc in Sources */, + E2D418C48F4925B014FD747F /* service_runtime.cc in Sources */, + BFF3632C5EB24BE9670698FE /* srpc_client.cc in Sources */, + 0DB9A2BCA231BDFE130F6B8D /* string_encoding.cc in Sources */, + D2D8713C4B46AB26971755AF /* utility.cc in Sources */, + 9086771531DDBA7130CC11B3 /* var_utils.cc in Sources */, + FFD5355ED935CD0CE1DB0DC9 /* sandbox_isa.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 0005E3D8CB9C2AE1CADEB22A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = jsoncpp; + targetProxy = 9CC5DA808C751EBA1C8143B3 /* PBXContainerItemProxy */; + }; + 28A4CB124CA2B051657AEF2E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = nacl_base; + targetProxy = 8125F53552AC6BAA042754A0 /* PBXContainerItemProxy */; + }; + 2C4B6AB54DCD38395A63D803 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = imc; + targetProxy = 0114BE6B01C2BFCBFFA9C7E6 /* PBXContainerItemProxy */; + }; + 3675EF172F844DAFBFF0E2E2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = gio; + targetProxy = 4A939CB2AC4C203830F317A1 /* PBXContainerItemProxy */; + }; + 3F98BC1B25AD8A573807D2AF /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = simple_service; + targetProxy = 58F04AB25BE810B74E971FF2 /* PBXContainerItemProxy */; + }; + 407313FDBF41F51C9868F0BE /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = ncval_base_x86_32; + targetProxy = CB2994AD5EAFAED788327646 /* PBXContainerItemProxy */; + }; + 585A0DA820803E5184141F8B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = gio_wrapped_desc; + targetProxy = 3238117537ECAAEEF7DFF138 /* PBXContainerItemProxy */; + }; + 5B1485C5A32E287D1BF39EB2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = nrd_xfer; + targetProxy = 66147BBC43F54931DB75356D /* PBXContainerItemProxy */; + }; + 75E414F600163EBE9E2CBE02 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = weak_ref; + targetProxy = 57EAAAA3D2C25E8B173C5BBA /* PBXContainerItemProxy */; + }; + 7CB32C0F5C85F1DB70579D63 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = env_cleanser; + targetProxy = 0AEC5EFF2D70143384D1636B /* PBXContainerItemProxy */; + }; + 7EFB31E6092DEC5CFA255855 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = platform_qual_lib; + targetProxy = 8EDCFFBB3BF791E2B675F8F8 /* PBXContainerItemProxy */; + }; + 994BC8BB87FBE94789E23A19 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = nacl_ppapi_browser; + targetProxy = 916A6F17D2A13C2ED4B2A21A /* PBXContainerItemProxy */; + }; + 9EE35712DD628F51DBF93B55 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = nonnacl_srpc; + targetProxy = E3AFD96A10B83D4ABAE4ABD4 /* PBXContainerItemProxy */; + }; + A14332ED112A67B8972E2D4F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = reverse_service; + targetProxy = A574CADB32986B354614D7B0 /* PBXContainerItemProxy */; + }; + A1D3403AA9994F940C3E099D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = ppapi_cpp_nacl; + targetProxy = 0758F97530AEDE3CE67BB0A6 /* PBXContainerItemProxy */; + }; + A5DA07C8D2E83C4050B36C4E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = sel_ldr_launcher; + targetProxy = 96E959948F294CC1864028C3 /* PBXContainerItemProxy */; + }; + AD275474C45A66D5EC683D3F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = platform; + targetProxy = 4867A7A2EA584A3D2CEBDBF5 /* PBXContainerItemProxy */; + }; + BBAD497F2A54F9A7B52EDE7E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = ppapi_cpp_objects_nacl; + targetProxy = CF908E2F4A70D4D9487AF27E /* PBXContainerItemProxy */; + }; + C61FC17A1D5066D2EC8BFAD7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = thread_interface; + targetProxy = 3162E403391EA6C55C8F9E2F /* PBXContainerItemProxy */; + }; + DC9B623BA9FB0CF747632F55 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = nacl_error_code; + targetProxy = 314B24CECA017C050099B1B5 /* PBXContainerItemProxy */; + }; + FDC6C4CBE7A04145B9622D91 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = nonnacl_util; + targetProxy = A199E645CD2A3BE4709F9A23 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 3D648ABA4E86EDA82E90BEA6 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + DEAD_CODE_STRIPPING = YES; + EXECUTABLE_PREFIX = lib; + GCC_CW_ASM_SYNTAX = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_CPP_EXCEPTIONS = NO; + GCC_ENABLE_CPP_RTTI = NO; + GCC_ENABLE_PASCAL_STRINGS = NO; + GCC_INLINES_ARE_PRIVATE_EXTERN = YES; + GCC_OBJC_CALL_CXX_CDTORS = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "\"NACL_BLOCK_SHIFT=5\"", + "\"NACL_BLOCK_SIZE=32\"", + "\"NACL_LINUX=0\"", + "\"NACL_OSX=1\"", + "\"NACL_WINDOWS=0\"", + "\"__STDC_FORMAT_MACROS\"", + "\"XP_MACOSX\"", + "\"XP_UNIX\"", + "\"TARGET_API_MAC_CARBON=1\"", + "\"NO_X11\"", + "\"USE_SYSTEM_CONSOLE\"", + "\"NACL_STANDALONE=1\"", + "\"NACL_TARGET_SUBARCH=32\"", + "\"NACL_TARGET_ARCH=x86\"", + "\"NACL_BUILD_SUBARCH=32\"", + "\"NACL_BUILD_ARCH=x86\"", + "\"NDEBUG\"", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GCC_THREADSAFE_STATICS = NO; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_VERSION = 4.2; + GCC_WARN_ABOUT_MISSING_NEWLINE = YES; + HEADER_SEARCH_PATHS = ( + ../../../../ppapi, + ../../../src/third_party, + ../../../.., + ); + LIBRARY_SEARCH_PATHS = "$(SDKROOT)/System/Library/Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_LDFLAGS = "-Wl,-search_paths_first"; + PREBINDING = NO; + PRODUCT_NAME = ppGoogleNaClPlugin; + SDKROOT = macosx10.5; + USE_HEADERMAP = NO; + WARNING_CFLAGS = ( + "-Wall", + "-Wendif-labels", + "-Wno-long-long", + "-Wextra", + "-Wno-long-long", + "-Wswitch-enum", + "-Wsign-compare", + "-Wno-deprecated", + "-Wno-deprecated-declarations", + ); + WARNING_CFLAGS_excluded = "-pedantic"; + }; + name = Release; + }; + 51903D509402D5D2E50F74A2 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + INTERMEDIATE_DIR = "$(PROJECT_DERIVED_FILE_DIR)/$(CONFIGURATION)"; + SHARED_INTERMEDIATE_DIR = "$(SYMROOT)/DerivedSources/$(CONFIGURATION)"; + SYMROOT = ../../../../xcodebuild; + }; + name = Release; + }; + B7D9EBCE9C63773A13B039E9 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + EXECUTABLE_PREFIX = lib; + GCC_CW_ASM_SYNTAX = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_CPP_EXCEPTIONS = NO; + GCC_ENABLE_CPP_RTTI = NO; + GCC_ENABLE_PASCAL_STRINGS = NO; + GCC_INLINES_ARE_PRIVATE_EXTERN = YES; + GCC_OBJC_CALL_CXX_CDTORS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "\"NACL_BLOCK_SHIFT=5\"", + "\"NACL_BLOCK_SIZE=32\"", + "\"NACL_LINUX=0\"", + "\"NACL_OSX=1\"", + "\"NACL_WINDOWS=0\"", + "\"__STDC_FORMAT_MACROS\"", + "\"XP_MACOSX\"", + "\"XP_UNIX\"", + "\"TARGET_API_MAC_CARBON=1\"", + "\"NO_X11\"", + "\"USE_SYSTEM_CONSOLE\"", + "\"NACL_STANDALONE=1\"", + "\"NACL_TARGET_SUBARCH=32\"", + "\"NACL_TARGET_ARCH=x86\"", + "\"NACL_BUILD_SUBARCH=32\"", + "\"NACL_BUILD_ARCH=x86\"", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GCC_THREADSAFE_STATICS = NO; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_VERSION = 4.2; + GCC_WARN_ABOUT_MISSING_NEWLINE = YES; + HEADER_SEARCH_PATHS = ( + ../../../../ppapi, + ../../../src/third_party, + ../../../.., + ); + LIBRARY_SEARCH_PATHS = "$(SDKROOT)/System/Library/Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_LDFLAGS = "-Wl,-search_paths_first"; + PREBINDING = NO; + PRODUCT_NAME = ppGoogleNaClPlugin; + SDKROOT = macosx10.5; + USE_HEADERMAP = NO; + WARNING_CFLAGS = ( + "-Wall", + "-Wendif-labels", + "-Wno-long-long", + "-Wextra", + "-Wno-long-long", + "-Wswitch-enum", + "-Wsign-compare", + "-Wno-deprecated", + "-Wno-deprecated-declarations", + ); + WARNING_CFLAGS_excluded = "-pedantic"; + }; + name = Debug; + }; + FDABDCC07C369BACD2986D07 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + INTERMEDIATE_DIR = "$(PROJECT_DERIVED_FILE_DIR)/$(CONFIGURATION)"; + SHARED_INTERMEDIATE_DIR = "$(SYMROOT)/DerivedSources/$(CONFIGURATION)"; + SYMROOT = ../../../../xcodebuild; + }; + name = Debug; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 0F67E6C4E63CA9C6E86EF43C /* Build configuration list for PBXProject "plugin" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FDABDCC07C369BACD2986D07 /* Debug */, + 51903D509402D5D2E50F74A2 /* Release */, + ); + defaultConfigurationIsVisible = 1; + defaultConfigurationName = Debug; + }; + 8FBD68EA480C8DB4E7449C10 /* Build configuration list for PBXNativeTarget "ppGoogleNaClPlugin" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B7D9EBCE9C63773A13B039E9 /* Debug */, + 3D648ABA4E86EDA82E90BEA6 /* Release */, + ); + defaultConfigurationIsVisible = 1; + defaultConfigurationName = Debug; + }; +/* End XCConfigurationList section */ + }; + rootObject = E9BF4284A4D7602AA0864CA3 /* Project object */; +} diff --git a/ppapi/native_client/src/trusted/plugin/plugin_error.h b/ppapi/native_client/src/trusted/plugin/plugin_error.h new file mode 100644 index 0000000..1bcecda --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/plugin_error.h @@ -0,0 +1,103 @@ +/* + * 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. + */ + +/* + * Error codes and data structures used to report errors when loading a nexe. + */ + +#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PLUGIN_ERROR_H +#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PLUGIN_ERROR_H + +#include <string> + +namespace plugin { + +// These error codes are reported via UMA so, if you edit them: +// 1) make sure you understand UMA, first. +// 2) update src/tools/histograms/histograms.xml in +// svn://svn.chromium.org/chrome-internal/trunk/src-internal +// Values are explicitly specified to make sure they don't shift around when +// edited, and also to make reading about:histograms easier. +enum PluginErrorCode { + ERROR_LOAD_SUCCESS = 0, + ERROR_LOAD_ABORTED = 1, + ERROR_UNKNOWN = 2, + ERROR_MANIFEST_RESOLVE_URL = 3, + ERROR_MANIFEST_LOAD_URL = 4, + ERROR_MANIFEST_STAT = 5, + ERROR_MANIFEST_TOO_LARGE = 6, + ERROR_MANIFEST_OPEN = 7, + ERROR_MANIFEST_MEMORY_ALLOC = 8, + ERROR_MANIFEST_READ = 9, + ERROR_MANIFEST_PARSING = 10, + ERROR_MANIFEST_SCHEMA_VALIDATE = 11, + ERROR_MANIFEST_GET_NEXE_URL = 12, + ERROR_NEXE_LOAD_URL = 13, + ERROR_NEXE_ORIGIN_PROTOCOL = 14, + ERROR_NEXE_FH_DUP = 15, + ERROR_NEXE_STAT = 16, + ERROR_ELF_CHECK_IO = 17, + ERROR_ELF_CHECK_FAIL = 18, + ERROR_SEL_LDR_INIT = 19, + ERROR_SEL_LDR_CREATE_LAUNCHER = 20, + ERROR_SEL_LDR_FD = 21, + ERROR_SEL_LDR_LAUNCH = 22, + // Deprecated, safe to reuse the # because never logged in UMA. + // ERROR_SEL_LDR_COMMUNICATION = 23, + ERROR_SEL_LDR_SEND_NEXE = 24, + ERROR_SEL_LDR_HANDLE_PASSING = 25, + ERROR_SEL_LDR_START_MODULE = 26, + ERROR_SEL_LDR_START_STATUS = 27, + ERROR_SRPC_CONNECTION_FAIL = 28, + ERROR_START_PROXY_CHECK_PPP = 29, + ERROR_START_PROXY_ALLOC = 30, + ERROR_START_PROXY_MODULE = 31, + ERROR_START_PROXY_INSTANCE = 32, + ERROR_SEL_LDR_COMMUNICATION_CMD_CHANNEL = 33, + ERROR_SEL_LDR_COMMUNICATION_REV_SETUP = 34, + ERROR_SEL_LDR_COMMUNICATION_WRAPPER = 35, + ERROR_SEL_LDR_COMMUNICATION_REV_SERVICE = 36, + ERROR_START_PROXY_CRASH = 37, + // If you add a code, read the enum comment above on how to update histograms. + ERROR_MAX +}; + +class ErrorInfo { + public: + ErrorInfo() { + Reset(); + } + + void Reset() { + SetReport(ERROR_UNKNOWN, ""); + } + + void SetReport(PluginErrorCode error_code, const std::string& message) { + error_code_ = error_code; + message_ = message; + } + + PluginErrorCode error_code() const { + return error_code_; + } + + void PrependMessage(const std::string& prefix) { + message_ = prefix + message_; + } + + const std::string& message() const { + return message_; + } + + private: + PluginErrorCode error_code_; + std::string message_; + NACL_DISALLOW_COPY_AND_ASSIGN(ErrorInfo); +}; + +} // namespace plugin + +#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PLUGIN_ERROR_H diff --git a/ppapi/native_client/src/trusted/plugin/plugin_unittest.cc b/ppapi/native_client/src/trusted/plugin/plugin_unittest.cc new file mode 100644 index 0000000..47e43d5 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/plugin_unittest.cc @@ -0,0 +1,60 @@ +// Copyright 2010 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. + +// Unit tests for ppGoogleNaClPlugin + +#include <stdio.h> + +#include "native_client/src/include/nacl_string.h" +#include "native_client/src/trusted/plugin/nexe_arch.h" +#include "native_client/src/trusted/plugin/dylib_unittest.h" + +// Verify that the ISA string returned by the plugin is the correct one for +// this platform. +bool TestGetNexeArch(DylibHandle dl_handle, const nacl::string& expected_isa) { + typedef const char* (*GetSandboxISAFunc)(); + GetSandboxISAFunc get_sandbox_isa_sym = reinterpret_cast<GetSandboxISAFunc>( + GetSymbolHandle(dl_handle, "NaClPluginGetSandboxISA")); + if (get_sandbox_isa_sym == NULL) + return false; + nacl::string sandbox_isa(get_sandbox_isa_sym()); + if (sandbox_isa != expected_isa) { + fprintf(stderr, "TestGetNexeArch ERROR: expeced ISA %s, got %s\n", + expected_isa.c_str(), sandbox_isa.c_str()); + return false; + } + return true; +} + +int main(int argc, char** argv) { + DylibHandle dl_handle = NULL; + + if (3 != argc) { + fprintf(stderr, "Usage: %s <plugin_name> <ISA_string>\n", argv[0]); + return 1; + } + // Test opening the dynamic library + dl_handle = DylibOpen(argv[1]); + if (NULL == dl_handle) { + fprintf(stderr, "Couldn't open: %s\n", argv[1]); + return 1; + } + + // Exercise some bare minimum functionality for PPAPI plugins. + bool success = TestGetNexeArch(dl_handle, argv[2]); + + // Test closing the dynamic library + if (!DylibClose(dl_handle)) { + fprintf(stderr, "Couldn't close: %s\n", argv[1]); + return 1; + } + + if (success) { + printf("PASS\n"); + return 0; + } else { + printf("FAIL\n"); + return 1; + } +} diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc new file mode 100644 index 0000000..eb48d6d --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc @@ -0,0 +1,734 @@ +// 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/trusted/plugin/pnacl_coordinator.h" + +#include <utility> +#include <vector> + +#include "native_client/src/include/portability_io.h" +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/src/trusted/desc/nacl_desc_wrapper.h" +#include "native_client/src/trusted/plugin/browser_interface.h" +#include "native_client/src/trusted/plugin/nacl_subprocess.h" +#include "native_client/src/trusted/plugin/nexe_arch.h" +#include "native_client/src/trusted/plugin/plugin.h" +#include "native_client/src/trusted/plugin/plugin_error.h" +#include "native_client/src/trusted/plugin/pnacl_srpc_lib.h" +#include "native_client/src/trusted/plugin/scriptable_handle.h" +#include "native_client/src/trusted/plugin/utility.h" + +#include "ppapi/c/pp_errors.h" + +namespace { + +typedef std::vector<nacl::string> string_vector; +int32_t kArbitraryStackSize = 128 << 10; + +} // namespace + +namespace plugin { + +class Plugin; + +void PnaclCoordinator::Initialize(Plugin* instance) { + PLUGIN_PRINTF(("PnaclCoordinator::Initialize (this=%p)\n", + static_cast<void*>(this))); + CHECK(instance != NULL); + CHECK(instance_ == NULL); // Can only initialize once. + instance_ = instance; + callback_factory_.Initialize(this); +} + +PnaclCoordinator::~PnaclCoordinator() { + PLUGIN_PRINTF(("PnaclCoordinator::~PnaclCoordinator (this=%p)\n", + static_cast<void*>(this))); + + // Delete helper thread args. Join helper thread first (since it may be + // using the args), which will block the page from Refreshing while a + // translation is happening. + if (translate_args_ != NULL) { + translate_args_->should_die = true; + // Assume that when X_args_ != NULL, then X_thread_ != NULL too. + NaClThreadJoin(translate_thread_.get()); + } + if (link_args_ != NULL) { + link_args_->should_die = true; + NaClThreadJoin(link_thread_.get()); + } + + // Delete all delayed_callbacks. + delayed_callbacks.erase(delayed_callbacks.begin(), delayed_callbacks.end()); + + for (std::map<nacl::string, nacl::DescWrapper*>::iterator + i = linker_resource_fds_.begin(), e = linker_resource_fds_.end(); + i != e; + ++i) { + delete i->second; + } + linker_resource_fds_.clear(); +} + +void PnaclCoordinator::ReportLoadAbort() { + instance_->ReportLoadAbort(); +} + +void PnaclCoordinator::ReportLoadError(const ErrorInfo& error) { + instance_->ReportLoadError(error); +} + +void PnaclCoordinator::PnaclPpapiError(int32_t pp_error) { + // Attempt to free all the intermediate callbacks we ever created. + callback_factory_.CancelAll(); + translate_notify_callback_.Run(pp_error); +} + +void PnaclCoordinator::PnaclNonPpapiError() { + PnaclPpapiError(PP_ERROR_FAILED); +} + +void PnaclCoordinator::PnaclDidFinish(int32_t pp_error) { + PLUGIN_PRINTF(("PnaclCoordinator::PnaclDidFinish (pp_error=%" + NACL_PRId32")\n", pp_error)); + translate_notify_callback_.Run(pp_error); +} + +////////////////////////////////////////////////////////////////////// + +DelayedCallback* +PnaclCoordinator::MakeDelayedCallback(pp::CompletionCallback cb, + uint32_t num_deps) { + DelayedCallback* delayed_callback = new DelayedCallback(cb, num_deps); + delayed_callbacks.insert(delayed_callback); + return delayed_callback; +} + +void PnaclCoordinator::SetObjectFile(NaClSrpcImcDescType fd, int32_t len) { + obj_fd_.reset(instance_->wrapper_factory()->MakeGeneric(fd)); + obj_len_ = len; +} + +void PnaclCoordinator::SetTranslatedFile(NaClSrpcImcDescType fd) { + translated_fd_.reset(instance_->wrapper_factory()->MakeGeneric(fd)); +} + +int32_t PnaclCoordinator::GetLoadedFileDesc(int32_t pp_error, + const nacl::string& url, + const nacl::string& component) { + ErrorInfo error_info; + int32_t file_desc = instance_->GetPOSIXFileDesc(url); + if (pp_error != PP_OK || file_desc == NACL_NO_FILE_DESC) { + if (pp_error == PP_ERROR_ABORTED) { + ReportLoadAbort(); + } else { + // TODO(jvoung): Make a generic load error, or just use ERROR_UNKNOWN? + error_info.SetReport(ERROR_UNKNOWN, + "PNaCl " + component + " load failed."); + ReportLoadError(error_info); + } + return -1; + } + int32_t file_desc_ok_to_close = DUP(file_desc); + if (file_desc_ok_to_close == NACL_NO_FILE_DESC) { + // TODO(jvoung): Make a generic load error, or just use ERROR_UNKNOWN? + error_info.SetReport(ERROR_UNKNOWN, + "PNaCl " + component + " load failed: " + "could not dup fd."); + ReportLoadError(error_info); + return -1; + } + return file_desc_ok_to_close; +} + +NaClSubprocessId PnaclCoordinator::HelperNexeDidLoad(int32_t fd, + ErrorInfo* error_info) { + // Inform JavaScript that we successfully loaded a helper nexe. + instance_->EnqueueProgressEvent("progress", + Plugin::LENGTH_IS_NOT_COMPUTABLE, + Plugin::kUnknownBytes, + Plugin::kUnknownBytes); + nacl::scoped_ptr<nacl::DescWrapper> + wrapper(instance_->wrapper_factory()->MakeFileDesc(fd, O_RDONLY)); + + return instance_->LoadHelperNaClModule(wrapper.get(), error_info); +} + +////////////////////////////////////////////////////////////////////// +// First few callbacks. + +void PnaclCoordinator::LLCReady(int32_t pp_error, + const nacl::string& llc_url, + DelayedCallback* delayed_callback) { + // pp_error is checked by GetLoadedFileDesc. + int32_t file_desc_ok_to_close = GetLoadedFileDesc(pp_error, llc_url, "llc"); + ErrorInfo error_info; + if (file_desc_ok_to_close < 0) { + PnaclPpapiError(pp_error); + return; + } + NaClSubprocessId llc_id = + HelperNexeDidLoad(file_desc_ok_to_close, &error_info); + PLUGIN_PRINTF(("PnaclCoordinator::LLCReady (pp_error=%" + NACL_PRId32" nexe_id=%" + NACL_PRId32")\n", + pp_error, + llc_id)); + if (kInvalidNaClSubprocessId == llc_id) { + error_info.SetReport(ERROR_UNKNOWN, + "Could not load pnacl compiler nexe"); + ReportLoadError(error_info); + PnaclNonPpapiError(); + return; + } + llc_subprocess_ = instance_ ->nacl_subprocess(llc_id); + delayed_callback->RunIfTime(); +} + +void PnaclCoordinator::LDReady(int32_t pp_error, + const nacl::string& ld_url, + DelayedCallback* delayed_callback) { + // pp_error is checked by GetLoadedFileDesc. + int32_t file_desc_ok_to_close = GetLoadedFileDesc(pp_error, ld_url, "ld"); + ErrorInfo error_info; + if (file_desc_ok_to_close < 0) { + PnaclPpapiError(pp_error); + return; + } + NaClSubprocessId ld_id = + HelperNexeDidLoad(file_desc_ok_to_close, &error_info); + PLUGIN_PRINTF(("PnaclCoordinator::LDReady (pp_error=%" + NACL_PRId32" nexe_id=%" + NACL_PRId32")\n", + pp_error, + ld_id)); + if (kInvalidNaClSubprocessId == ld_id) { + error_info.SetReport(ERROR_UNKNOWN, + "Could not load pnacl linker nexe"); + ReportLoadError(error_info); + PnaclNonPpapiError(); + return; + } + ld_subprocess_ = instance_ ->nacl_subprocess(ld_id); + delayed_callback->RunIfTime(); +} + +void PnaclCoordinator::PexeReady(int32_t pp_error, + const nacl::string& pexe_url, + DelayedCallback* delayed_callback) { + PLUGIN_PRINTF(("PnaclCoordinator::PexeReady (pp_error=%" + NACL_PRId32")\n", pp_error)); + // pp_error is checked by GetLoadedFileDesc. + int32_t fd = GetLoadedFileDesc(pp_error, pexe_url, "pexe"); + if (fd < 0) { + PnaclPpapiError(pp_error); + } else { + pexe_fd_.reset(instance_->wrapper_factory()->MakeFileDesc(fd, O_RDONLY)); + delayed_callback->RunIfTime(); + } +} + +void PnaclCoordinator::LinkResourceReady(int32_t pp_error, + const nacl::string& url, + DelayedCallback* delayed_callback) { + PLUGIN_PRINTF(("PnaclCoordinator::LinkResourceReady (pp_error=%" + NACL_PRId32", url=%s)\n", pp_error, url.c_str())); + // pp_error is checked by GetLoadedFileDesc. + int32_t fd = GetLoadedFileDesc(pp_error, url, "linker resource " + url); + if (fd < 0) { + PnaclPpapiError(pp_error); + } else { + linker_resource_fds_[url] = + instance_->wrapper_factory()->MakeFileDesc(fd, O_RDONLY); + delayed_callback->RunIfTime(); + } +} + +////////////////////////////////////////////////////////////////////// + +namespace { +void AbortTranslateThread(DoTranslateArgs* args, + const nacl::string& error_string) { + pp::Core* core = pp::Module::Get()->core(); + args->error_info.SetReport(ERROR_UNKNOWN, error_string); + core->CallOnMainThread(0, args->finish_cb, PP_ERROR_FAILED); + NaClThreadExit(1); +} +} // namespace + +void WINAPI DoTranslateThread(void* arg) { + DoTranslateArgs* p = reinterpret_cast<DoTranslateArgs*>(arg); + NaClSubprocess* llc_subprocess = p->subprocess; + + // Set up LLC flags first. + // TODO(jvoung): Bake these into the llc nexe? + // May also want to improve scriptability, but the only thing we need + // probably is PIC vs non-PIC and micro-arch specification. + const char* llc_args_x8632[] = { "-march=x86", + "-mcpu=pentium4", + "-mtriple=i686-none-linux-gnu", + "-asm-verbose=false", + "-filetype=obj" }; + const char* llc_args_x8664[] = { "-march=x86-64", + "-mcpu=core2", + "-mtriple=x86_64-none-linux-gnu", + "-asm-verbose=false", + "-filetype=obj" }; + const char* llc_args_arm[] = { "-march=arm", + "-mcpu=cortex-a8", + "-mtriple=armv7a-none-linux-gnueabi", + "-asm-verbose=false", + "-filetype=obj", + "-arm-reserve-r9", + "-sfi-disable-cp", + "-arm_static_tls", + "-sfi-store -sfi-stack -sfi-branch -sfi-data", + "-no-inline-jumptables" }; + + nacl::string sandbox_isa = GetSandboxISA(); + const char** llc_args; + size_t num_args; + + if (sandbox_isa.compare("x86-32") == 0) { + llc_args = llc_args_x8632; + num_args = NACL_ARRAY_SIZE(llc_args_x8632); + } else if (sandbox_isa.compare("x86-64") == 0) { + llc_args = llc_args_x8664; + num_args = NACL_ARRAY_SIZE(llc_args_x8664); + } else if (sandbox_isa.compare("arm") == 0) { + llc_args = llc_args_arm; + num_args = NACL_ARRAY_SIZE(llc_args_arm); + } else { + AbortTranslateThread(p, + "PnaclCoordinator compiler unhandled ISA " + + sandbox_isa + "."); + return; + } + + for (uint32_t i = 0; i < num_args; i++) { + if (p->should_die) { + NaClThreadExit(1); + } + SrpcParams dummy_params; + if (!PnaclSrpcLib::InvokeSrpcMethod(p->browser, + llc_subprocess, + "AddArg", + "C", + &dummy_params, + llc_args[i])) { + AbortTranslateThread(p, + "PnaclCoordinator compiler AddArg(" + + nacl::string(llc_args[i]) + ") failed."); + } + } + + if (p->should_die) { + NaClThreadExit(1); + } + SrpcParams params; + if (!PnaclSrpcLib::InvokeSrpcMethod(p->browser, + llc_subprocess, + "Translate", + "h", + ¶ms, + p->pexe_fd->desc())) { + AbortTranslateThread(p, + "PnaclCoordinator compile failed."); + } else { + // Grab the outparams. + p->obj_fd = params.outs()[0]->u.hval; + p->obj_len = params.outs()[1]->u.ival; + PLUGIN_PRINTF(("PnaclCoordinator::InvokeTranslate succeeded (bytes=%" + NACL_PRId32")\n", p->obj_len)); + } + if (p->should_die) { + NaClThreadExit(1); + } + pp::Core* core = pp::Module::Get()->core(); + core->CallOnMainThread(0, p->finish_cb, PP_OK); + NaClThreadExit(0); +} + +void +PnaclCoordinator::RunTranslateDidFinish(int32_t pp_error, + DelayedCallback* delayed_callback) { + PLUGIN_PRINTF(("PnaclCoordinator::RunTranslateDidFinish (pp_error=%" + NACL_PRId32")\n", pp_error)); + if (pp_error != PP_OK) { + ReportLoadError(translate_args_->error_info); + PnaclPpapiError(pp_error); + return; + } + SetObjectFile(translate_args_->obj_fd, translate_args_->obj_len); + instance_->EnqueueProgressEvent("progress", + Plugin::LENGTH_IS_NOT_COMPUTABLE, + Plugin::kUnknownBytes, + Plugin::kUnknownBytes); + delayed_callback->RunIfTime(); +} + +void PnaclCoordinator::RunTranslate(int32_t pp_error, + DelayedCallback* delayed_callback) { + PLUGIN_PRINTF(("PnaclCoordinator::RunTranslate (pp_error=%" + NACL_PRId32")\n", pp_error)); + assert(PP_OK == pp_error); + + // Invoke llvm asynchronously. + pp::CompletionCallback finish_cb = + callback_factory_.NewCallback(&PnaclCoordinator::RunTranslateDidFinish, + delayed_callback); + translate_args_.reset(new DoTranslateArgs(llc_subprocess_, + instance_->browser_interface(), + finish_cb, + pexe_fd_.get())); + translate_thread_.reset(new NaClThread); + if (translate_thread_ != NULL && translate_args_ != NULL) { + if (!NaClThreadCreateJoinable(translate_thread_.get(), + DoTranslateThread, + translate_args_.get(), + kArbitraryStackSize)) { + ErrorInfo error_info; + error_info.SetReport(ERROR_UNKNOWN, + "Could not create a translator thread.\n"); + ReportLoadError(error_info); + PnaclNonPpapiError(); + } + } else { + ErrorInfo error_info; + error_info.SetReport(ERROR_UNKNOWN, + "Could not allocate DoTranslateThread()\n"); + ReportLoadError(error_info); + PnaclNonPpapiError(); + } +} + +////////////////////////////////////////////////////////////////////// +// Helper functions for loading native libs. +// Done here to avoid hacking on the manifest parser further... + +namespace { + +// Fake filename for the object file generated by llvm. +const nacl::string kGeneratedObjectFileName = + nacl::string("___PNACL_GENERATED"); + +string_vector LinkResources(const nacl::string& sandbox_isa, + bool withGenerated) { + string_vector results; + nacl::string base_dir = "pnacl_support/" + sandbox_isa; + + // NOTE: order of items == link order. + if (withGenerated) { + results.push_back(kGeneratedObjectFileName); + } + results.push_back(base_dir + "/libcrt_platform.a"); + results.push_back(base_dir + "/libgcc.a"); + results.push_back(base_dir + "/libgcc_eh.a"); + return results; +} + +} // namespace + +////////////////////////////////////////////////////////////////////// +// Final link callbacks. + +namespace { + +void AbortLinkThread(DoLinkArgs* args, const nacl::string& error_string) { + ErrorInfo error_info; + pp::Core* core = pp::Module::Get()->core(); + args->error_info.SetReport(ERROR_UNKNOWN, error_string); + core->CallOnMainThread(0, args->finish_cb, PP_ERROR_FAILED); + NaClThreadExit(1); +} + +} // namespace + +void WINAPI DoLinkThread(void* arg) { + DoLinkArgs* p = reinterpret_cast<DoLinkArgs*>(arg); + NaClSubprocess* ld_subprocess = p->subprocess; + + // Set up command line arguments (flags then files). + + //// Flags. + // TODO(jvoung): Be able to handle the dynamic linking flags too, + // and don't hardcode so much here. + string_vector flags; + nacl::string sandbox_isa = GetSandboxISA(); + flags.push_back("-nostdlib"); + flags.push_back("-m"); + if (sandbox_isa.compare("x86-32") == 0) { + flags.push_back("elf_nacl"); + } else if (sandbox_isa.compare("x86-64") == 0) { + flags.push_back("elf64_nacl"); + } else if (sandbox_isa.compare("arm") == 0) { + flags.push_back("armelf_nacl"); + } else { + AbortLinkThread(p, + "PnaclCoordinator linker unhandled ISA " + + sandbox_isa + "."); + } + + for (string_vector::iterator i = flags.begin(), e = flags.end(); + i != e; ++i) { + const nacl::string& flag = *i; + if (p->should_die) { + NaClThreadExit(1); + } + SrpcParams dummy_params; + if (!PnaclSrpcLib::InvokeSrpcMethod(p->browser, + ld_subprocess, + "AddArg", + "C", + &dummy_params, + flag.c_str())) { + AbortLinkThread(p, + "PnaclCoordinator linker AddArg(" + flag + + ") failed."); + } + } + + //// Files. + PnaclCoordinator* pnacl = p->coordinator; + string_vector files = LinkResources(sandbox_isa, true); + for (string_vector::iterator i = files.begin(), e = files.end(); + i != e; ++i) { + const nacl::string& link_file = *i; + if (p->should_die) { + NaClThreadExit(1); + } + // Add as argument. + SrpcParams dummy_params; + if (!PnaclSrpcLib::InvokeSrpcMethod(p->browser, + ld_subprocess, + "AddArg", + "C", + &dummy_params, + link_file.c_str())) { + AbortLinkThread(p, + "PnaclCoordinator linker AddArg(" + + link_file + ") failed."); + } + // Also map the file name to descriptor. + if (i->compare(kGeneratedObjectFileName) == 0) { + SrpcParams dummy_params2; + if (!PnaclSrpcLib::InvokeSrpcMethod(p->browser, + ld_subprocess, + "AddFileWithSize", + "Chi", + &dummy_params2, + link_file.c_str(), + p->obj_fd->desc(), + p->obj_len)) { + AbortLinkThread(p, + "PnaclCoordinator linker AddFileWithSize" + "(" + link_file + ") failed."); + } + } else { + SrpcParams dummy_params2; + if (!PnaclSrpcLib::InvokeSrpcMethod(p->browser, + ld_subprocess, + "AddFile", + "Ch", + &dummy_params2, + link_file.c_str(), + pnacl->GetLinkerResourceFD( + link_file))) { + AbortLinkThread(p, + "PnaclCoordinator linker AddFile(" + link_file + + ") failed."); + } + } + } + + if (p->should_die) { + NaClThreadExit(1); + } + + // Finally, do the Link! + SrpcParams params; + if (!PnaclSrpcLib::InvokeSrpcMethod(p->browser, + ld_subprocess, + "Link", + "", + ¶ms)) { + AbortLinkThread(p, "PnaclCoordinator link failed."); + } else { + // Grab the outparams. + p->nexe_fd = params.outs()[0]->u.hval; + int32_t nexe_size = params.outs()[1]->u.ival; // only for debug. + PLUGIN_PRINTF(("PnaclCoordinator::InvokeLink succeeded (bytes=%" + NACL_PRId32")\n", nexe_size)); + } + if (p->should_die) { + NaClThreadExit(1); + } + pp::Core* core = pp::Module::Get()->core(); + core->CallOnMainThread(0, p->finish_cb, PP_OK); + NaClThreadExit(0); +} + +void PnaclCoordinator::RunLinkDidFinish(int32_t pp_error) { + PLUGIN_PRINTF(("PnaclCoordinator::RunLinkDidFinish (pp_error=%" + NACL_PRId32")\n", pp_error)); + if (pp_error != PP_OK) { + ReportLoadError(link_args_->error_info); + PnaclPpapiError(pp_error); + return; + } + SetTranslatedFile(link_args_->nexe_fd); + instance_->EnqueueProgressEvent("progress", + Plugin::LENGTH_IS_NOT_COMPUTABLE, + Plugin::kUnknownBytes, + Plugin::kUnknownBytes); + PnaclDidFinish(PP_OK); +} + +void PnaclCoordinator::RunLink(int32_t pp_error) { + PLUGIN_PRINTF(("PnaclCoordinator::RunLink (pp_error=%" + NACL_PRId32")\n", pp_error)); + assert(PP_OK == pp_error); + + // Invoke llvm asynchronously. + pp::CompletionCallback finish_cb = + callback_factory_.NewCallback(&PnaclCoordinator::RunLinkDidFinish); + link_args_.reset(new DoLinkArgs(ld_subprocess_, + instance_->browser_interface(), + finish_cb, + this, + obj_fd_.get(), + obj_len_)); + link_thread_.reset(new NaClThread); + if (link_args_ != NULL && link_thread_ != NULL) { + if (!NaClThreadCreateJoinable(link_thread_.get(), + DoLinkThread, + link_args_.get(), + kArbitraryStackSize)) { + ErrorInfo error_info; + error_info.SetReport(ERROR_UNKNOWN, + "Could not create a linker thread.\n"); + ReportLoadError(error_info); + PnaclNonPpapiError(); + } + } else { + ErrorInfo error_info; + error_info.SetReport(ERROR_UNKNOWN, + "Could not allocate DoLinkThread()\n"); + ReportLoadError(error_info); + PnaclNonPpapiError(); + } +} + +////////////////////////////////////////////////////////////////////// + +bool PnaclCoordinator::ScheduleDownload(const nacl::string& url, + const pp::CompletionCallback& cb) { + if (!instance_->StreamAsFile(url, + cb.pp_completion_callback())) { + ErrorInfo error_info; + error_info.SetReport(ERROR_UNKNOWN, + "PnaclCoordinator: Failed to download file: " + + url + "\n"); + ReportLoadError(error_info); + PnaclNonPpapiError(); + return false; + } + return true; +} + +void PnaclCoordinator::AddDownloadToDelayedCallback( + void (PnaclCoordinator::*handler)(int32_t, + const nacl::string&, + DelayedCallback*), + DelayedCallback* delayed_callback, + const nacl::string& url, + std::vector<url_callback_pair>& queue) { + // Queue up the URL download w/ a callback that invokes the delayed_callback. + queue.push_back(std::make_pair( + url, + callback_factory_.NewCallback(handler, + url, + delayed_callback))); + delayed_callback->IncrRequirements(1); +} + +void PnaclCoordinator::BitcodeToNative( + const nacl::string& pexe_url, + const nacl::string& llc_url, + const nacl::string& ld_url, + const pp::CompletionCallback& finish_callback) { + PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (pexe=%s, llc=%s, ld=%s)\n", + pexe_url.c_str(), + llc_url.c_str(), + ld_url.c_str())); + translate_notify_callback_ = finish_callback; + + string_vector link_resources = LinkResources(GetSandboxISA(), false); + + // Steps: + // (1) Schedule downloads for llc, ld nexes, and native libraries. + // (2) When llc download and pexe has completed, run the translation. + // (3) When llc translation has finished, and ld, native libs are available, + // do the link. + // (4) When the link is done, we are done, call the finish_callback. + // Hand off the SHM file descriptor returned by link. + + // Set up async callbacks for these steps in reverse order. + + // (3) Run link. + + pp::CompletionCallback run_link_callback = + callback_factory_.NewCallback(&PnaclCoordinator::RunLink); + DelayedCallback* delayed_link_callback = + MakeDelayedCallback(run_link_callback, 0); + + // (2) Run translation. + pp::CompletionCallback run_translate_callback = + callback_factory_.NewCallback(&PnaclCoordinator::RunTranslate, + delayed_link_callback); + // Linking depends on the compile finishing, so incr requirements by one. + delayed_link_callback->IncrRequirements(1); + + DelayedCallback* delayed_translate_callback = MakeDelayedCallback( + run_translate_callback, 0); + + // (1) Load nexes and assets using StreamAsFile(). This will kick off + // the whole process. + + // First, just collect the list of stuff to download. + std::vector<url_callback_pair> downloads; + + AddDownloadToDelayedCallback(&PnaclCoordinator::PexeReady, + delayed_translate_callback, + pexe_url, + downloads); + AddDownloadToDelayedCallback(&PnaclCoordinator::LLCReady, + delayed_translate_callback, + llc_url, + downloads); + AddDownloadToDelayedCallback(&PnaclCoordinator::LDReady, + delayed_link_callback, + ld_url, + downloads); + for (string_vector::iterator + i = link_resources.begin(), e = link_resources.end(); + i != e; + ++i) { + AddDownloadToDelayedCallback(&PnaclCoordinator::LinkResourceReady, + delayed_link_callback, + *i, + downloads); + } + + // Finally, actually schedule the downloads. + for (size_t i = 0; i < downloads.size(); ++i) { + if (!ScheduleDownload(downloads[i].first, downloads[i].second)) { + break; // error should have been reported by ScheduleDownload. + } + } + downloads.clear(); + + return; +} + +} // namespace plugin diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h new file mode 100644 index 0000000..7fded68 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h @@ -0,0 +1,190 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_COORDINATOR_H_ +#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_COORDINATOR_H_ + +#include <set> +#include <map> +#include <vector> + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/nacl_string.h" +#include "native_client/src/shared/platform/nacl_threads.h" +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "native_client/src/trusted/desc/nacl_desc_wrapper.h" +#include "native_client/src/trusted/plugin/delayed_callback.h" +#include "native_client/src/trusted/plugin/nacl_subprocess.h" +#include "native_client/src/trusted/plugin/plugin_error.h" +#include "native_client/src/trusted/plugin/pnacl_thread_args.h" + +#include "ppapi/cpp/completion_callback.h" + +namespace plugin { + +class Plugin; +struct DoTranslateArgs; +struct DoLinkArgs; + +typedef std::pair<nacl::string, pp::CompletionCallback> url_callback_pair; + +// A class that handles PNaCl client-side translation. +// Usage: +// (1) Initialize(); +// (2) BitcodeToNative(bitcode, ..., finish_callback); +// (3) After finish_callback runs, do: +// fd = ReleaseTranslatedFD(); +// (4) go ahead and load the nexe from "fd" +// (5) delete +class PnaclCoordinator { + public: + PnaclCoordinator() + : instance_(NULL), + translate_notify_callback_(pp::BlockUntilComplete()), + llc_subprocess_(NULL), + ld_subprocess_(NULL), + obj_len_(-1), + translate_args_(NULL), + link_args_(NULL) { + } + + virtual ~PnaclCoordinator(); + + // Initialize() can only be called once during the lifetime of this instance. + void Initialize(Plugin* instance); + + void BitcodeToNative(const nacl::string& pexe_url, + const nacl::string& llc_url, + const nacl::string& ld_url, + const pp::CompletionCallback& finish_callback); + + // Call this to take ownership of the FD of the translated nexe after + // BitcodeToNative has completed (and the finish_callback called). + nacl::DescWrapper* ReleaseTranslatedFD() { + return translated_fd_.release(); + } + + // This method should really be private, but it is used to + // communicate with the linker thread. + NaClSrpcImcDescType GetLinkerResourceFD(const nacl::string& url) { + return linker_resource_fds_[url]->desc(); + } + + protected: + + void SetObjectFile(NaClSrpcImcDescType fd, int32_t len); + void SetTranslatedFile(NaClSrpcImcDescType fd); + + // Delay a callback until |num_dependencies| are met. + DelayedCallback* MakeDelayedCallback(pp::CompletionCallback cb, + uint32_t num_dependencies); + + // Helper function for generating callbacks that will be run when a + // download of |url| has completed. The generated callback will + // run |handler|. The |handler| itself is given a pp_error code, + // the url of the download, and another callback in the + // form of the supplied |delayed_callback|. + void AddDownloadToDelayedCallback( + void (PnaclCoordinator::*handler)(int32_t, + const nacl::string&, + DelayedCallback*), + DelayedCallback* delayed_callback, + const nacl::string& url, + std::vector<url_callback_pair>& queue); + + bool ScheduleDownload(const nacl::string& url, + const pp::CompletionCallback& cb); + + // Callbacks for when various files, etc. have been downloaded. + void PexeReady(int32_t pp_error, + const nacl::string& url, + DelayedCallback* delayed_callback); + void LLCReady(int32_t pp_error, + const nacl::string& url, + DelayedCallback* delayed_callback); + void LDReady(int32_t pp_error, + const nacl::string& url, + DelayedCallback* delayed_callback); + void LinkResourceReady(int32_t pp_error, + const nacl::string& url, + DelayedCallback* delayed_callback); + + int32_t GetLoadedFileDesc(int32_t pp_error, + const nacl::string& url, + const nacl::string& component); + + // Helper for starting helper nexes after they are downloaded. + NaClSubprocessId HelperNexeDidLoad(int32_t fd, ErrorInfo* error_info); + + // Callbacks for compute-based translation steps. + void RunTranslate(int32_t pp_error, DelayedCallback* delayed_callback); + void RunTranslateDidFinish(int32_t pp_error, + DelayedCallback* delayed_callback); + void RunLink(int32_t pp_error); + void RunLinkDidFinish(int32_t pp_error); + + // Pnacl translation completed normally. + void PnaclDidFinish(int32_t pp_error); + + // Run when faced with a PPAPI error condition. It brings control back to the + // plugin by invoking the |translate_notify_callback_|. + void PnaclPpapiError(int32_t pp_error); + + // Run |translate_notify_callback_| with an error condition that is not + // PPAPI specific. + void PnaclNonPpapiError(); + + // Wrapper for Plugin ReportLoadAbort. + void ReportLoadAbort(); + // Wrapper for Plugin ReportLoadError. + void ReportLoadError(const ErrorInfo& error); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(PnaclCoordinator); + + Plugin* instance_; + pp::CompletionCallback translate_notify_callback_; + pp::CompletionCallbackFactory<PnaclCoordinator> callback_factory_; + + // State for a single translation. + // TODO(jvoung): see if we can manage this state better, especially when we + // start having to translate multiple bitcode files for the same application + // (for DSOs). + + std::set<DelayedCallback*> delayed_callbacks; + + // Helper subprocess loaded by the plugin (deleted by the plugin). + // We may want to do cleanup ourselves when we are in the + // business of compiling multiple bitcode objects / libraries, and + // if we truly cannot reuse existing loaded subprocesses. + NaClSubprocess* llc_subprocess_; + NaClSubprocess* ld_subprocess_; + + // Bitcode file pulled from the Net. + nacl::scoped_ptr<nacl::DescWrapper> pexe_fd_; + + // Object "file" obtained after compiling with LLVM, along with the length + // of the "file". + nacl::scoped_ptr<nacl::DescWrapper> obj_fd_; + int32_t obj_len_; + + // Nexe from the final native Link. + nacl::scoped_ptr<nacl::DescWrapper> translated_fd_; + + // Perhaps make this a single thread that invokes (S)RPCs followed by + // callbacks based on a Queue of requests. A generic mechanism would make + // it easier to add steps later (the mechanism could look like PostMessage?). + nacl::scoped_ptr<DoTranslateArgs> translate_args_; + nacl::scoped_ptr<NaClThread> translate_thread_; + + nacl::scoped_ptr<DoLinkArgs> link_args_; + nacl::scoped_ptr<NaClThread> link_thread_; + + std::map<nacl::string, nacl::DescWrapper*> linker_resource_fds_; +}; + +//---------------------------------------------------------------------- + +} // namespace plugin; +#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_COORDINATOR_H_ diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_srpc_lib.cc b/ppapi/native_client/src/trusted/plugin/pnacl_srpc_lib.cc new file mode 100644 index 0000000..dbddd69 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/pnacl_srpc_lib.cc @@ -0,0 +1,111 @@ +// 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/trusted/plugin/pnacl_srpc_lib.h" + +#include <stdarg.h> + +#include "native_client/src/trusted/plugin/browser_interface.h" +#include "native_client/src/trusted/plugin/method_map.h" +#include "native_client/src/trusted/plugin/nacl_subprocess.h" + +namespace plugin { + +bool PnaclSrpcLib::InvokeSrpcMethod(BrowserInterface* browser_interface, + const NaClSubprocess* subprocess, + const nacl::string& method_name, + const nacl::string& input_signature, + SrpcParams* params, + ...) { + va_list vl; + va_start(vl, params); + bool result = VInvokeSrpcMethod(browser_interface, + subprocess, + method_name, + input_signature, + params, + vl); + va_end(vl); + return result; +} + +bool PnaclSrpcLib::VInvokeSrpcMethod(BrowserInterface* browser_interface, + const NaClSubprocess* subprocess, + const nacl::string& method_name, + const nacl::string& input_signature, + SrpcParams* params, + va_list vl) { + uintptr_t kMethodIdent; + if (!SetupSrpcInvocation(browser_interface, + subprocess, + method_name, + params, + &kMethodIdent)) { + return false; + } + + // Set up inputs. + for (size_t i = 0; i < input_signature.length(); ++i) { + char c = input_signature[i]; + // Only handle the limited number of SRPC types used for PNaCl. + // Add more as needed. + switch (c) { + default: + PLUGIN_PRINTF(("PnaclSrpcLib::InvokeSrpcMethod unhandled type: %c\n", + c)); + return false; + case NACL_SRPC_ARG_TYPE_BOOL: { + int input = va_arg(vl, int); + params->ins()[i]->u.bval = input; + break; + } + case NACL_SRPC_ARG_TYPE_DOUBLE: { + double input = va_arg(vl, double); + params->ins()[i]->u.dval = input; + break; + } + case NACL_SRPC_ARG_TYPE_CHAR_ARRAY: { + // SrpcParam's destructor *should* free the dup'ed string. + const char* orig_str = va_arg(vl, const char*); + char* input = strdup(orig_str); + params->ins()[i]->arrays.str = input; + break; + } + case NACL_SRPC_ARG_TYPE_HANDLE: { + NaClSrpcImcDescType input = va_arg(vl, NaClSrpcImcDescType); + params->ins()[i]->u.hval = input; + break; + } + case NACL_SRPC_ARG_TYPE_INT: { + int32_t input = va_arg(vl, int32_t); + params->ins()[i]->u.ival = input; + break; + } + case NACL_SRPC_ARG_TYPE_LONG: { + int64_t input = va_arg(vl, int64_t); + params->ins()[i]->u.lval = input; + break; + } + } + } + + return subprocess->Invoke(kMethodIdent, params); +} + + +bool PnaclSrpcLib::SetupSrpcInvocation(BrowserInterface* browser_interface, + const NaClSubprocess* subprocess, + const nacl::string& method_name, + SrpcParams* params, + uintptr_t* kMethodIdent) { + *kMethodIdent = browser_interface->StringToIdentifier(method_name); + if (!(subprocess->HasMethod(*kMethodIdent))) { + PLUGIN_PRINTF(("SetupSrpcInvocation (no %s method found)\n", + method_name.c_str())); + return false; + } + return subprocess->InitParams(*kMethodIdent, params); +} + +} // namespace plugin diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_srpc_lib.h b/ppapi/native_client/src/trusted/plugin/pnacl_srpc_lib.h new file mode 100644 index 0000000..9e764c9 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/pnacl_srpc_lib.h @@ -0,0 +1,61 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_SRPC_LIB_H_ +#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_SRPC_LIB_H_ + +// Routines to simplify SRPC invocations. + +#include <stdarg.h> +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/nacl_string.h" +#include "native_client/src/include/portability.h" + +namespace plugin { + +class BrowserInterface; +class NaClSubprocess; +class SrpcParams; + +// TODO(jvoung): See if anything can be shared between this and +// src/shared/srpc/invoke.c + +// This is just a namespace to collect methods for setting up and invoking +// SPRC methods against a NaClSubprocess. +class PnaclSrpcLib { + public: + // Invoke an Srpc Method on the NaCl subprocess |subprocess|. + // |out_params| must be allocated and cleaned up outside of this function, + // but it will be initialized by this function, and on success + // any out-params (if any) will be placed in |out_params|. + // Input types must be listed in |input_signature|, with the actual + // arguments passed in as var-args. + // Returns |true| on success. + static bool InvokeSrpcMethod(BrowserInterface* browser_interface, + const NaClSubprocess* subprocess, + const nacl::string& method_name, + const nacl::string& input_signature, + SrpcParams* out_params, + ...); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(PnaclSrpcLib); + + static bool SetupSrpcInvocation(BrowserInterface* browser_interface, + const NaClSubprocess* subprocess, + const nacl::string& method_name, + SrpcParams* params, + uintptr_t* kMethodIdent); + + static bool VInvokeSrpcMethod(BrowserInterface* browser_interface, + const NaClSubprocess* subprocess, + const nacl::string& method_name, + const nacl::string& signature, + SrpcParams* params, + va_list vl); +}; + +} // namespace plugin; + +#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_SRPC_LIB_H_ diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_thread_args.h b/ppapi/native_client/src/trusted/plugin/pnacl_thread_args.h new file mode 100644 index 0000000..ae766c3 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/pnacl_thread_args.h @@ -0,0 +1,97 @@ +// 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. + +#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_THREAD_ARGS_H_ +#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_THREAD_ARGS_H_ + +#include "native_client/src/trusted/plugin/plugin_error.h" + +#include "ppapi/cpp/completion_callback.h" + +namespace plugin { + +class BrowserInterface; +class NaClSubprocess; +class PnaclCoordinator; + +// Base structure for storing pnacl helper thread arguments. +struct PnaclThreadArgs { + PnaclThreadArgs(NaClSubprocess* subprocess_, + BrowserInterface* browser_, + pp::CompletionCallback finish_cb_) + : should_die(false), + subprocess(subprocess_), + browser(browser_), + finish_cb(finish_cb_) { + } + + // Bool to signal to the thread that it should end whenever possible. + bool should_die; + + // SRPC Nexe subprocess that does the work. + NaClSubprocess* subprocess; + // Browser Interface for SRPC setup. + BrowserInterface* browser; + + // Callback to run when task is completed or an error has occurred. + pp::CompletionCallback finish_cb; + + ErrorInfo error_info; +}; + +//---------------------------------------------------------------------- +// Helper thread arguments. + +// TODO(jvoung): Move these to the compile / link files when we separate +// those bits from pnacl_coordinator. + +// Arguments needed to run LLVM in a separate thread, to go from +// bitcode -> object file. This prevents LLVM from blocking the main thread. +struct DoTranslateArgs : PnaclThreadArgs { + DoTranslateArgs(NaClSubprocess* subprocess_, + BrowserInterface* browser_, + pp::CompletionCallback finish_cb_, + nacl::DescWrapper* pexe_fd_) + : PnaclThreadArgs(subprocess_, browser_, finish_cb_), + pexe_fd(pexe_fd_), + obj_fd(kNaClSrpcInvalidImcDesc), + obj_len(-1) { + } + + // Borrowed references which must outlive the thread. + nacl::DescWrapper* pexe_fd; + + // Output. + NaClSrpcImcDescType obj_fd; + int32_t obj_len; +}; + +// Arguments needed to run LD in a separate thread, to go from +// object file -> nexe. +struct DoLinkArgs : PnaclThreadArgs { + DoLinkArgs(NaClSubprocess* subprocess_, + BrowserInterface* browser_, + pp::CompletionCallback finish_cb_, + PnaclCoordinator* coordinator_, + nacl::DescWrapper* obj_fd_, + int32_t obj_len_) + : PnaclThreadArgs(subprocess_, browser_, finish_cb_), + coordinator(coordinator_), + obj_fd(obj_fd_), + obj_len(obj_len_), + nexe_fd(kNaClSrpcInvalidImcDesc) { + } + PnaclCoordinator* coordinator; // Punch hole in abstraction. + + // Borrowed references which must outlive the thread. + nacl::DescWrapper* obj_fd; + int32_t obj_len; + + // Output. + NaClSrpcImcDescType nexe_fd; +}; + + +} // namespace plugin; +#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_THREAD_ARGS_H_ diff --git a/ppapi/native_client/src/trusted/plugin/ppapi.def b/ppapi/native_client/src/trusted/plugin/ppapi.def new file mode 100644 index 0000000..b9643e8 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/ppapi.def @@ -0,0 +1,3 @@ +_PPP_GetInterface +_PPP_InitializeModule +_PPP_ShutdownModule diff --git a/ppapi/native_client/src/trusted/plugin/scriptable_handle.cc b/ppapi/native_client/src/trusted/plugin/scriptable_handle.cc new file mode 100644 index 0000000..2e173ea --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/scriptable_handle.cc @@ -0,0 +1,477 @@ +/* + * Copyright 2011 (c) 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. + */ + + +// Scriptable handle implementation. + +#include "native_client/src/trusted/plugin/scriptable_handle.h" + +#include <stdio.h> +#include <string.h> + +#include <assert.h> +#include <set> +#include <sstream> +#include <string> +#include <vector> + + +#include "native_client/src/include/checked_cast.h" +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/nacl_string.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "native_client/src/trusted/plugin/array_ppapi.h" +#include "native_client/src/trusted/plugin/browser_interface.h" +#include "native_client/src/trusted/plugin/desc_based_handle.h" +#include "native_client/src/trusted/plugin/method_map.h" +#include "native_client/src/trusted/plugin/plugin.h" +#include "native_client/src/trusted/plugin/utility.h" +#include "native_client/src/trusted/plugin/var_utils.h" + + +namespace plugin { + +namespace { + +// For security we keep track of the set of scriptable handles that were +// created. + +std::set<const plugin::ScriptableHandle*>* g_ValidHandles = 0; + +void RememberValidHandle(const ScriptableHandle* handle) { + // Initialize the set. + // BUG: this is not thread safe. We may leak sets, or worse, may not + // correctly insert valid handles into the set. + // TODO(sehr): use pthread_once or similar initialization. + if (NULL == g_ValidHandles) { + g_ValidHandles = new(std::nothrow) std::set<const ScriptableHandle*>; + if (NULL == g_ValidHandles) { + return; + } + } + // Remember the handle. + g_ValidHandles->insert(handle); +} + +pp::Var Error(nacl::string call_name, const char* caller, + const char* error, pp::Var* exception) { + nacl::stringstream error_stream; + error_stream << call_name << ": " << error; + if (!exception->is_undefined()) { + error_stream << " - " + exception->AsString(); + } + // Get the error string in 2 steps; otherwise, the temporary string returned + // by the stream is destructed, causing a dangling pointer. + std::string str = error_stream.str(); + const char* e = str.c_str(); + PLUGIN_PRINTF(("ScriptableHandle::%s (%s)\n", caller, e)); + *exception = pp::Var(e); + return pp::Var(); +} + +// Helper functionality common to HasProperty and HasMethod. +bool HasCallType(Plugin* plugin, + CallType call_type, + nacl::string call_name, + const char* caller) { + uintptr_t id = plugin->browser_interface()->StringToIdentifier(call_name); + PLUGIN_PRINTF(("ScriptableHandle::%s (id=%"NACL_PRIxPTR")\n", + caller, id)); + return plugin->HasMethod(id, call_type); +} + +// Helper functionality common to GetProperty, SetProperty and Call. +// If |call_type| is PROPERTY_GET, ignores args and expects 1 return var. +// If |call_type| is PROPERTY_SET, expects 1 arg and returns void var. +// Sets |exception| on failure. +pp::Var Invoke(Plugin* plugin, + CallType call_type, + nacl::string call_name, + const char* caller, + const std::vector<pp::Var>& args, + pp::Var* exception) { + uintptr_t id = plugin->browser_interface()->StringToIdentifier(call_name); + + // Initialize input/output parameters. + SrpcParams params; + NaClSrpcArg** inputs = params.ins(); + NaClSrpcArg** outputs = params.outs(); + if (!plugin->InitParams(id, call_type, ¶ms)) { + return Error(call_name, caller, + "srpc parameter initialization failed", exception); + } + uint32_t input_length = params.InputLength(); + int32_t output_length = params.OutputLength(); + PLUGIN_PRINTF(("ScriptableHandle::%s (initialized %"NACL_PRIu32" ins, %" + NACL_PRIu32" outs)\n", caller, input_length, output_length)); + + // Verify input/output parameter list length. + if (args.size() != params.SignatureLength()) { + return Error(call_name, caller, + "incompatible srpc parameter list", exception); + } + PLUGIN_PRINTF(("ScriptableHandle::%s (verified signature)\n", caller)); + + // Marshall input parameters. + if (input_length > 0) { + assert(call_type != PROPERTY_GET); // expect no inputs for "get" + for (int i = 0; (i < NACL_SRPC_MAX_ARGS) && (inputs[i] != NULL); ++i) { + if (!PPVarToNaClSrpcArg(args[i], inputs[i], exception)) { + return Error(call_name, caller, + "srpc input marshalling failed", exception); + } + } + } + if (call_type == PROPERTY_SET) assert(input_length == 1); + PLUGIN_PRINTF(("ScriptableHandle::%s (marshalled inputs)\n", caller)); + + // Allocate array-typed output parameters. + if (args.size() > input_length) { + for (int i = 0; (i < NACL_SRPC_MAX_ARGS) && (outputs[i] != NULL); ++i) { + if (!PPVarToAllocateNaClSrpcArg(args[input_length + i], + outputs[i], exception)) { + return Error(call_name, caller, "srpc output array allocation failed", + exception); + } + } + } + PLUGIN_PRINTF(("ScriptableHandle::%s (output array allocation done)\n", + caller)); + + // Invoke. + if (!plugin->Invoke(id, call_type, ¶ms)) { + nacl::string err = nacl::string(caller) + "('" + call_name + "') failed\n"; + if (params.exception_string() != NULL) { + err = params.exception_string(); + } + *exception = pp::Var(err.c_str()); + return Error(call_name, caller, "invocation failed", exception); + } + PLUGIN_PRINTF(("ScriptableHandle::%s (invocation done)\n", caller)); + + // Marshall output parameters. + pp::Var retvar; + if (output_length > 0) { + assert(call_type != PROPERTY_SET); // expect no outputs for "set" + retvar = NaClSrpcArgToPPVar(outputs[0], plugin, exception); + if (output_length > 1) { + ArrayPpapi* array = new(std::nothrow) ArrayPpapi(plugin); + if (array == NULL) { + *exception = pp::Var("failed to allocate output array"); + } else { + array->SetProperty(pp::Var(0), retvar, exception); + for (int32_t i = 1; i < output_length; ++i) { + pp::Var v = NaClSrpcArgToPPVar(outputs[i], plugin, exception); + array->SetProperty(pp::Var(i), v, exception); + } + } + + retvar = pp::VarPrivate(plugin, array); + } + if (!exception->is_undefined()) { + return Error(call_name, caller, "srpc output marshalling failed", + exception); + } + } + if (call_type == PROPERTY_GET) assert(output_length == 1); + return retvar; +} + +} // namespace + +ScriptableHandle::ScriptableHandle(Plugin* plugin) + : var_(NULL), num_unref_calls_(0), plugin_(plugin), desc_handle_(NULL) { + PLUGIN_PRINTF(("ScriptableHandle::ScriptableHandle (this=%p, plugin=%p)\n", + static_cast<void*>(this), + static_cast<void*>(plugin))); + RememberValidHandle(this); + PLUGIN_PRINTF(("ScriptableHandle::ScriptableHandle (this=%p)\n", + static_cast<void*>(this))); +} + +ScriptableHandle::ScriptableHandle(DescBasedHandle* desc_handle) + : var_(NULL), num_unref_calls_(0), plugin_(NULL), desc_handle_(desc_handle) { + PLUGIN_PRINTF(("ScriptableHandle::ScriptableHandle (this=%p," + " desc_handle=%p)\n", + static_cast<void*>(this), + static_cast<void*>(desc_handle))); + RememberValidHandle(this); + PLUGIN_PRINTF(("ScriptableHandle::ScriptableHandle (this=%p)\n", + static_cast<void*>(this))); +} + +ScriptableHandle::~ScriptableHandle() { + PLUGIN_PRINTF(("ScriptableHandle::~ScriptableHandle (this=%p)\n", + static_cast<void*>(this))); + // If the set was empty, just return. + if (NULL == g_ValidHandles) { + return; + } + // Remove the scriptable handle from the set of valid handles. + g_ValidHandles->erase(this); + // If handle is a plugin, the browser is deleting it (and might have + // already done so). Otherwise, delete here. + if (desc_handle_ != NULL) { + PLUGIN_PRINTF(("ScriptableHandle::~ScriptableHandle " + "(this=%p, delete desc_handle=%p)\n", + static_cast<void*>(this), static_cast<void*>(desc_handle_))); + delete desc_handle_; + desc_handle_ = NULL; + } + PLUGIN_PRINTF(("ScriptableHandle::~ScriptableHandle (this=%p, return)\n", + static_cast<void*>(this))); +} + +// Check that an object is a validly created ScriptableHandle. +bool ScriptableHandle::is_valid(const ScriptableHandle* handle) { + PLUGIN_PRINTF(("ScriptableHandle::is_valid (handle=%p)\n", + static_cast<void*>(const_cast<ScriptableHandle*>(handle)))); + if (NULL == g_ValidHandles) { + PLUGIN_PRINTF(("ScriptableHandle::is_valid (return 0)\n")); + return false; + } + size_t count = + g_ValidHandles->count(static_cast<const ScriptableHandle*>(handle)); + PLUGIN_PRINTF(("ScriptableHandle::is_valid (handle=%p, count=%" + NACL_PRIuS")\n", + static_cast<void*>(const_cast<ScriptableHandle*>(handle)), + count)); + return 0 != count; +} + +void ScriptableHandle::Unref(ScriptableHandle** handle) { + if (*handle != NULL) { + (*handle)->Unref(); + *handle = NULL; + } +} + +ScriptableHandle* ScriptableHandle::NewPlugin(Plugin* plugin) { + PLUGIN_PRINTF(("ScriptableHandle::NewPlugin (plugin=%p)\n", + static_cast<void*>(plugin))); + if (plugin == NULL) { + return NULL; + } + ScriptableHandle* scriptable_handle = + new(std::nothrow) ScriptableHandle(plugin); + if (scriptable_handle == NULL) { + return NULL; + } + PLUGIN_PRINTF(("ScriptableHandle::NewPlugin (return %p)\n", + static_cast<void*>(scriptable_handle))); + return scriptable_handle; +} + + +ScriptableHandle* ScriptableHandle::NewDescHandle( + DescBasedHandle* desc_handle) { + PLUGIN_PRINTF(("ScriptableHandle::NewDescHandle (desc_handle=%p)\n", + static_cast<void*>(desc_handle))); + if (desc_handle == NULL) { + return NULL; + } + ScriptableHandle* scriptable_handle = + new(std::nothrow) ScriptableHandle(desc_handle); + if (scriptable_handle == NULL) { + return NULL; + } + PLUGIN_PRINTF(("ScriptableHandle::NewDescHandle (return %p)\n", + static_cast<void*>(scriptable_handle))); + return scriptable_handle; +} + + +bool ScriptableHandle::HasProperty(const pp::Var& name, pp::Var* exception) { + UNREFERENCED_PARAMETER(exception); + PLUGIN_PRINTF(("ScriptableHandle::HasProperty (this=%p, name=%s)\n", + static_cast<void*>(this), name.DebugString().c_str())); + if (plugin_ == NULL) { + return false; + } + if (!name.is_string() && !name.is_int()) + return false; + bool has_property = HasCallType(plugin_, + PROPERTY_GET, + name.AsString(), + "HasProperty"); + PLUGIN_PRINTF(("ScriptableHandle::HasProperty (has_property=%d)\n", + has_property)); + return has_property; +} + + +bool ScriptableHandle::HasMethod(const pp::Var& name, pp::Var* exception) { + UNREFERENCED_PARAMETER(exception); + PLUGIN_PRINTF(("ScriptableHandle::HasMethod (this=%p, name='%s')\n", + static_cast<void*>(this), name.DebugString().c_str())); + if (plugin_ == NULL) { + return false; + } + if (!name.is_string()) + return false; + bool has_method = HasCallType(plugin_, + METHOD_CALL, + name.AsString(), + "HasMethod"); + PLUGIN_PRINTF(("ScriptableHandle::HasMethod (has_method=%d)\n", + has_method)); + return has_method; +} + + +pp::Var ScriptableHandle::GetProperty(const pp::Var& name, + pp::Var* exception) { + PLUGIN_PRINTF(("ScriptableHandle::GetProperty (name=%s)\n", + name.DebugString().c_str())); + if (plugin_ == NULL) { + return pp::Var(); + } + pp::Var property = Invoke(plugin_, + PROPERTY_GET, + NameAsString(name), + "GetProperty", + std::vector<pp::Var>(), exception); + PLUGIN_PRINTF(("ScriptableHandle::GetProperty (property=%s)\n", + property.DebugString().c_str())); + return property; +} + + +void ScriptableHandle::SetProperty(const pp::Var& name, + const pp::Var& value, + pp::Var* exception) { + PLUGIN_PRINTF(("ScriptableHandle::SetProperty (name=%s, value=%s)\n", + name.DebugString().c_str(), value.DebugString().c_str())); + if (plugin_ == NULL) { + return; + } + std::vector<pp::Var> args; + args.push_back(pp::Var(pp::Var::DontManage(), value.pp_var())); + Invoke(plugin_, + PROPERTY_SET, + NameAsString(name), + "SetProperty", + args, + exception); + std::string exception_string("NULL"); + if (exception != NULL) { + exception_string = exception->DebugString(); + } + PLUGIN_PRINTF(("ScriptableHandle::SetProperty (exception=%s)\n", + exception_string.c_str())); +} + + +void ScriptableHandle::RemoveProperty(const pp::Var& name, + pp::Var* exception) { + PLUGIN_PRINTF(("ScriptableHandle::RemoveProperty (name=%s)\n", + name.DebugString().c_str())); + Error(NameAsString(name), "RemoveProperty", + "property removal is not supported", exception); +} + +// TODO(polina): should methods also be added? +// This is currently never called and the exact semantics is not clear. +// http://code.google.com/p/chromium/issues/detail?id=51089 +void ScriptableHandle::GetAllPropertyNames(std::vector<pp::Var>* properties, + pp::Var* exception) { + UNREFERENCED_PARAMETER(exception); + PLUGIN_PRINTF(("ScriptableHandle::GetAllPropertyNames ()\n")); + if (plugin_ == NULL) { + return; + } + std::vector<uintptr_t>* ids = plugin_->GetPropertyIdentifiers(); + if (ids == NULL) { + PLUGIN_PRINTF(("ScriptableHandle::GetAllPropertyNames " + "(ids=%p)\n", reinterpret_cast<void*>(ids))); + return; + } + PLUGIN_PRINTF(("ScriptableHandle::GetAllPropertyNames " + "(ids->size()=%"NACL_PRIuS")\n", ids->size())); + for (size_t i = 0; i < ids->size(); ++i) { + nacl::string name = + plugin_->browser_interface()->IdentifierToString(ids->at(i)); + properties->push_back(pp::Var(name)); + } + PLUGIN_PRINTF(("ScriptableHandle::GetAllPropertyNames " + "(properties=%"NACL_PRIuS")\n", properties->size())); +} + + +pp::Var ScriptableHandle::Call(const pp::Var& name, + const std::vector<pp::Var>& args, + pp::Var* exception) { + PLUGIN_PRINTF(("ScriptableHandle::Call (name=%s, %"NACL_PRIuS + " args)\n", name.DebugString().c_str(), args.size())); + if (plugin_ == NULL) { + pp::Var(); + } + if (name.is_undefined()) // invoke default + return pp::Var(); + assert(name.is_string()); + pp::Var return_var = Invoke(plugin_, + METHOD_CALL, + name.AsString(), + "Call", + args, + exception); + PLUGIN_PRINTF(("ScriptableHandle::Call (return=%s)\n", + return_var.DebugString().c_str())); + return return_var; +} + + +pp::Var ScriptableHandle::Construct(const std::vector<pp::Var>& args, + pp::Var* exception) { + PLUGIN_PRINTF(("ScriptableHandle::Construct (%"NACL_PRIuS + " args)\n", args.size())); + return Error("constructor", "Construct", "constructor is not supported", + exception); +} + + +ScriptableHandle* ScriptableHandle::AddRef() { + // This is called when we are about to share this object with the browser, + // and we need to make sure we have an internal plugin reference, so this + // object doesn't get deallocated when the browser discards its references. + if (var_ == NULL) { + var_ = new(std::nothrow) pp::VarPrivate(plugin_, this); + CHECK(var_ != NULL); + } + PLUGIN_PRINTF(("ScriptableHandle::AddRef (this=%p, var=%p)\n", + static_cast<void*>(this), static_cast<void*>(var_))); + return this; +} + + +void ScriptableHandle::Unref() { + // We should have no more than one internal owner of this object, so this + // should be called no more than once. + CHECK(++num_unref_calls_ == 1); + PLUGIN_PRINTF(("ScriptableHandle::Unref (this=%p, var=%p)\n", + static_cast<void*>(this), static_cast<void*>(var_))); + if (var_ != NULL) { + // We have shared this with the browser while keeping our own var + // reference, but we no longer need ours. If the browser has copies, + // it will clean things up later, otherwise this object will get + // deallocated right away. + PLUGIN_PRINTF(("ScriptableHandle::Unref (delete var)\n")); + pp::Var* var = var_; + var_ = NULL; + delete var; + } else { + // Neither the browser nor plugin ever var referenced this object, + // so it can safely discarded. + PLUGIN_PRINTF(("ScriptableHandle::Unref (delete this)\n")); + CHECK(var_ == NULL); + delete this; + } +} + + +} // namespace plugin diff --git a/ppapi/native_client/src/trusted/plugin/scriptable_handle.h b/ppapi/native_client/src/trusted/plugin/scriptable_handle.h new file mode 100644 index 0000000..4719265 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/scriptable_handle.h @@ -0,0 +1,139 @@ +/* + * Copyright 2011 (c) 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. + */ + + +// The browser scriptable container class. The methods on this class +// are defined in the specific API directories. + +#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_SCRIPTABLE_HANDLE_H_ +#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_SCRIPTABLE_HANDLE_H_ + +#include "native_client/src/trusted/plugin/scriptable_handle.h" + +#include <stdio.h> +#include <string.h> + +#include <set> +#include <string> +#include <vector> + +#include "native_client/src/include/checked_cast.h" +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/nacl_string.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/trusted/plugin/utility.h" +#include "ppapi/cpp/dev/scriptable_object_deprecated.h" +#include "ppapi/cpp/private/var_private.h" + +struct NaClDesc; + +namespace plugin { + +// Forward declarations for externals. +class DescBasedHandle; +class Plugin; + +// ScriptableHandle encapsulates objects that are scriptable from the browser. +class ScriptableHandle : public pp::deprecated::ScriptableObject { + public: + // Factory methods for creation. + static ScriptableHandle* NewPlugin(Plugin* plugin); + static ScriptableHandle* NewDescHandle(DescBasedHandle* desc_handle); + + // If not NULL, this var should be reused to pass this object to the browser. + pp::VarPrivate* var() { return var_; } + + // Check that a pointer is to a validly created ScriptableHandle. + static bool is_valid(const ScriptableHandle* handle); + static void Unref(ScriptableHandle** handle); + + // Get the contained plugin object. NULL if this contains a descriptor. + Plugin* plugin() const { return plugin_; } + + // Get the contained descriptor object. NULL if this contains a plugin. + // OBSOLETE -- this support is only needed for SRPC descriptor passing. + // TODO(polina): Remove this support when SRPC descriptor passing is removed. + DescBasedHandle* desc_handle() const { return desc_handle_; } + + // This function is called when we are about to share the object owned by the + // plugin with the browser. Since reference counting on the browser side is + // handled via pp::Var's, we create the var() here if not created already. + ScriptableHandle* AddRef(); + // Remove a browser reference to this object. + // Delete the object when the ref count becomes 0. + // If var() is set, we delete it. Otherwise, we delete the object itself. + // Therefore, this cannot be called more than once. + void Unref(); + + // ------ Methods inherited from pp::deprecated::ScriptableObject: + + // Returns true for preloaded NaCl Plugin properties. + // Does not set |exception|. + virtual bool HasProperty(const pp::Var& name, pp::Var* exception); + // Returns true for preloaded NaCl Plugin methods and SRPC methods exported + // from a NaCl module. Does not set |exception|. + virtual bool HasMethod(const pp::Var& name, pp::Var* exception); + + // Gets the value of a preloaded NaCl Plugin property. + // Sets |exception| on failure. + virtual pp::Var GetProperty(const pp::Var& name, pp::Var* exception); + // Sets the value of a preloaded NaCl Plugin property. + // Does not add new properties. Sets |exception| of failure. + virtual void SetProperty(const pp::Var& name, const pp::Var& value, + pp::Var* exception); + // Set |exception| to indicate that property removal is not supported. + virtual void RemoveProperty(const pp::Var& name, pp::Var* exception); + // Returns a list of all preloaded NaCl Plugin |properties|. + // Does not set |exception|. + virtual void GetAllPropertyNames(std::vector<pp::Var>* properties, + pp::Var* exception); + + // Calls preloaded NaCl Plugin methods or SRPC methods exported from + // a NaCl module. Sets |exception| on failure. + virtual pp::Var Call(const pp::Var& name, const std::vector<pp::Var>& args, + pp::Var* exception); + + // Sets |exception| to indicate that constructor is not supported. + virtual pp::Var Construct(const std::vector<pp::Var>& args, + pp::Var* exception); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(ScriptableHandle); + // Prevent construction from outside the class: must use factory New() + // method instead. + explicit ScriptableHandle(Plugin* plugin); + explicit ScriptableHandle(DescBasedHandle* desc_handle); + // This will be called when both the plugin and the browser clear all + // references to this object. + virtual ~ScriptableHandle(); + + // When we pass the object owned by the plugin to the browser, we need to wrap + // it in a pp::VarPrivate, which also registers the object with the browser + // for refcounting. It must be registered only once with all other var + // references being copies of the original one. Thus, we record the + // pp::VarPrivate here and reuse it when satisfiying additional browser + // requests. This way we also ensure that when the browser clears its + // references, this object does not get deallocated while we still hold ours. + // This is never set for objects that are not shared with the browser nor for + // objects created during SRPC calls as they are taken over by the browser on + // return. + pp::VarPrivate* var_; + + // We should have no more than one internal plugin owner for this object, + // and only that owner should call Unref(). To CHECK for that keep a counter. + int num_unref_calls_; + + // The contained plugin object. + Plugin* plugin_; + // OBSOLETE -- this support is only needed for SRPC descriptor passing. + // TODO(polina): Remove this support when SRPC descriptor passing is removed. + // The contained descriptor handle object. + DescBasedHandle* desc_handle_; +}; + +} // namespace plugin + +#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_SCRIPTABLE_HANDLE_H_ diff --git a/ppapi/native_client/src/trusted/plugin/service_runtime.cc b/ppapi/native_client/src/trusted/plugin/service_runtime.cc new file mode 100644 index 0000000..1fea5de --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/service_runtime.cc @@ -0,0 +1,550 @@ +/* + * 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. + */ + +#define NACL_LOG_MODULE_NAME "Plugin::ServiceRuntime" + +#include "native_client/src/trusted/plugin/service_runtime.h" + +#include <string.h> +#include <map> +#include <set> +#include <string> +#include <utility> +#include <vector> + +#include "native_client/src/include/portability_io.h" +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/nacl_string.h" +#include "native_client/src/shared/imc/nacl_imc.h" +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/src/shared/platform/nacl_log.h" +#include "native_client/src/shared/platform/nacl_sync.h" +#include "native_client/src/shared/platform/nacl_sync_checked.h" +#include "native_client/src/shared/platform/nacl_sync_raii.h" +#include "native_client/src/shared/platform/scoped_ptr_refcount.h" +#include "native_client/src/trusted/desc/nacl_desc_imc.h" +#include "native_client/src/trusted/desc/nrd_xfer.h" +#include "native_client/src/trusted/desc/nrd_xfer_effector.h" +#include "native_client/src/trusted/handle_pass/browser_handle.h" +#include "native_client/src/trusted/nonnacl_util/sel_ldr_launcher.h" + +#include "native_client/src/trusted/plugin/browser_interface.h" +#include "native_client/src/trusted/plugin/manifest.h" +#include "native_client/src/trusted/plugin/plugin.h" +#include "native_client/src/trusted/plugin/plugin_error.h" +#include "native_client/src/trusted/plugin/scriptable_handle.h" +#include "native_client/src/trusted/plugin/srpc_client.h" +#include "native_client/src/trusted/plugin/utility.h" + +#include "native_client/src/trusted/weak_ref/call_on_main_thread.h" + +#include "native_client/src/trusted/service_runtime/nacl_error_code.h" +#include "native_client/src/trusted/service_runtime/include/sys/nacl_imc_api.h" + +#include "ppapi/c/pp_errors.h" +#include "ppapi/cpp/core.h" +#include "ppapi/cpp/completion_callback.h" + +using std::vector; + +namespace plugin { + +PluginReverseInterface::PluginReverseInterface( + nacl::WeakRefAnchor* anchor, + Plugin* plugin, + pp::CompletionCallback init_done_cb) + : anchor_(anchor), + plugin_(plugin), + shutting_down_(false), + init_done_cb_(init_done_cb) { + NaClXMutexCtor(&mu_); + NaClXCondVarCtor(&cv_); +} + +PluginReverseInterface::~PluginReverseInterface() { + NaClCondVarDtor(&cv_); + NaClMutexDtor(&mu_); +} + +void PluginReverseInterface::ShutDown() { + nacl::MutexLocker take(&mu_); + shutting_down_ = true; + NaClXCondVarBroadcast(&cv_); +} + +void PluginReverseInterface::Log(nacl::string message) { + LogToJavaScriptConsoleResource* continuation = + new LogToJavaScriptConsoleResource(message); + CHECK(continuation != NULL); + NaClLog(4, "PluginReverseInterface::Log(%s)\n", message.c_str()); + plugin::WeakRefCallOnMainThread( + anchor_, + 0, /* delay in ms */ + this, + &plugin::PluginReverseInterface::Log_MainThreadContinuation, + continuation); +} + +void PluginReverseInterface::StartupInitializationComplete() { + NaClLog(0, "PluginReverseInterface::StartupInitializationComplete\n"); + if (init_done_cb_.pp_completion_callback().func != NULL) { + NaClLog(0, + "PluginReverseInterface::StartupInitializationComplete:" + " invoking CB\n"); + pp::Module::Get()->core()->CallOnMainThread(0, init_done_cb_, PP_OK); + } else { + NaClLog(0, + "PluginReverseInterface::StartupInitializationComplete:" + " init_done_cb_ not valid, skipping.\n"); + } +} + +void PluginReverseInterface::Log_MainThreadContinuation( + LogToJavaScriptConsoleResource* p, + int32_t err) { + UNREFERENCED_PARAMETER(err); + NaClLog(4, + "PluginReverseInterface::Log_MainThreadContinuation(%s)\n", + p->message.c_str()); + plugin_->browser_interface()->AddToConsole(static_cast<Plugin*>(plugin_), + p->message); +} + +bool PluginReverseInterface::EnumerateManifestKeys( + std::set<nacl::string>* out_keys) { + Manifest const* mp = plugin_->manifest(); + + if (!mp->GetFileKeys(out_keys)) { + return false; + } + + return true; +} + +// TODO(bsy): OpenManifestEntry should use the manifest to ResolveKey +// and invoke StreamAsFile with a completion callback that invokes +// GetPOSIXFileDesc. +bool PluginReverseInterface::OpenManifestEntry(nacl::string url_key, + int32_t* out_desc) { + ErrorInfo error_info; + bool is_portable = false; + bool op_complete = false; // NB: mu_ and cv_ also controls access to this! + OpenManifestEntryResource* to_open = + new OpenManifestEntryResource(url_key, out_desc, + &error_info, &is_portable, &op_complete); + CHECK(to_open != NULL); + NaClLog(4, "PluginReverseInterface::OpenManifestEntry: %s\n", + url_key.c_str()); + // This assumes we are not on the main thread. If false, we deadlock. + plugin::WeakRefCallOnMainThread( + anchor_, + 0, + this, + &plugin::PluginReverseInterface::OpenManifestEntry_MainThreadContinuation, + to_open); + NaClLog(4, + "PluginReverseInterface::OpenManifestEntry:" + " waiting on main thread\n"); + bool shutting_down; + do { + nacl::MutexLocker take(&mu_); + for (;;) { + NaClLog(4, + "PluginReverseInterface::OpenManifestEntry:" + " got lock, checking shutdown and completion: (%s, %s)\n", + shutting_down_ ? "yes" : "no", + op_complete ? "yes" : "no"); + shutting_down = shutting_down_; + if (op_complete || shutting_down) { + NaClLog(4, + "PluginReverseInterface::OpenManifestEntry:" + " done!\n"); + break; + } + NaClXCondVarWait(&cv_, &mu_); + } + } while (0); + if (shutting_down) { + NaClLog(4, + "PluginReverseInterface::OpenManifestEntry:" + " plugin is shutting down\n"); + return false; + } + // out_desc has the returned descriptor if successful, else -1. + + // The caller is responsible for not closing *out_desc. If it is + // closed prematurely, then another open could re-use the OS + // descriptor, confusing the opened_ map. If the caller is going to + // want to make a NaClDesc object and transfer it etc., then the + // caller should DUP the descriptor (but remember the original + // value) for use by the NaClDesc object, which closes when the + // object is destroyed. + NaClLog(4, + "PluginReverseInterface::OpenManifestEntry:" + " *out_desc = %d\n", + *out_desc); + if (*out_desc == -1) { + // TODO(bsy,ncbray): what else should we do with the error? This + // is a runtime error that may simply be a programming error in + // the untrusted code, or it may be something else wrong w/ the + // manifest. + NaClLog(4, + "OpenManifestEntry: failed for key %s, code %d (%s)\n", + url_key.c_str(), + error_info.error_code(), + error_info.message().c_str()); + } + return true; +} + +void PluginReverseInterface::OpenManifestEntry_MainThreadContinuation( + OpenManifestEntryResource* p, + int32_t err) { + OpenManifestEntryResource *open_cont; + UNREFERENCED_PARAMETER(err); + // CallOnMainThread continuations always called with err == PP_OK. + + NaClLog(4, "Entered OpenManifestEntry_MainThreadContinuation\n"); + + std::string mapped_url; + if (!plugin_->manifest()->ResolveKey(p->url, &mapped_url, + p->error_info, p->is_portable)) { + NaClLog(4, "OpenManifestEntry_MainThreadContinuation: ResolveKey failed\n"); + // Failed, and error_info has the details on what happened. Wake + // up requesting thread -- we are done. + nacl::MutexLocker take(&mu_); + *p->op_complete_ptr = true; // done... + *p->out_desc = -1; // but failed. + NaClXCondVarBroadcast(&cv_); + return; + } + NaClLog(4, + "OpenManifestEntry_MainThreadContinuation: ResolveKey: %s -> %s\n", + p->url.c_str(), mapped_url.c_str()); + + open_cont = new OpenManifestEntryResource(*p); // copy ctor! + CHECK(open_cont != NULL); + open_cont->url = mapped_url; + pp::CompletionCallback stream_cc = WeakRefNewCallback( + anchor_, + this, + &PluginReverseInterface::StreamAsFile_MainThreadContinuation, + open_cont); + if (!plugin_->StreamAsFile(mapped_url, stream_cc.pp_completion_callback())) { + NaClLog(4, + "OpenManifestEntry_MainThreadContinuation: StreamAsFile failed\n"); + nacl::MutexLocker take(&mu_); + *p->op_complete_ptr = true; // done... + *p->out_desc = -1; // but failed. + p->error_info->SetReport(ERROR_MANIFEST_OPEN, + "ServiceRuntime: StreamAsFile failed"); + NaClXCondVarBroadcast(&cv_); + return; + } + NaClLog(4, + "OpenManifestEntry_MainThreadContinuation: StreamAsFile okay\n"); + // p is deleted automatically +} + +void PluginReverseInterface::StreamAsFile_MainThreadContinuation( + OpenManifestEntryResource* p, + int32_t result) { + NaClLog(4, + "Entered StreamAsFile_MainThreadContinuation\n"); + + nacl::MutexLocker take(&mu_); + if (result == PP_OK) { + NaClLog(4, "StreamAsFile_MainThreadContinuation: GetPOSIXFileDesc(%s)\n", + p->url.c_str()); + *p->out_desc = plugin_->GetPOSIXFileDesc(p->url); + NaClLog(4, + "StreamAsFile_MainThreadContinuation: PP_OK, desc %d\n", + *p->out_desc); + } else { + NaClLog(4, + "StreamAsFile_MainThreadContinuation: !PP_OK, setting desc -1\n"); + *p->out_desc = -1; + p->error_info->SetReport(ERROR_MANIFEST_OPEN, + "Plugin StreamAsFile failed at callback"); + } + *p->op_complete_ptr = true; + NaClXCondVarBroadcast(&cv_); +} + +bool PluginReverseInterface::CloseManifestEntry(int32_t desc) { + bool op_complete; + bool op_result; + CloseManifestEntryResource* to_close = + new CloseManifestEntryResource(desc, &op_complete, &op_result); + + bool shutting_down; + plugin::WeakRefCallOnMainThread( + anchor_, + 0, + this, + &plugin::PluginReverseInterface:: + CloseManifestEntry_MainThreadContinuation, + to_close); + // wait for completion or surf-away. + do { + nacl::MutexLocker take(&mu_); + for (;;) { + shutting_down = shutting_down_; + if (op_complete || shutting_down) { + break; + } + NaClXCondVarWait(&cv_, &mu_); + } + } while (0); + + if (shutting_down) return false; + // op_result true if close was successful; false otherwise (e.g., bad desc). + return op_result; +} + +void PluginReverseInterface::CloseManifestEntry_MainThreadContinuation( + CloseManifestEntryResource* cls, + int32_t err) { + UNREFERENCED_PARAMETER(err); + + nacl::MutexLocker take(&mu_); + // TODO(bsy): once the plugin has a reliable way to report that the + // file usage is done -- and sel_ldr uses this RPC call -- we should + // tell the plugin that the associated resources can be freed. + *cls->op_result_ptr = true; + *cls->op_complete_ptr = true; + NaClXCondVarBroadcast(&cv_); + // cls automatically deleted +} + +ServiceRuntime::ServiceRuntime(Plugin* plugin, + pp::CompletionCallback init_done_cb) + : plugin_(plugin), + browser_interface_(plugin->browser_interface()), + reverse_service_(NULL), + subprocess_(NULL), + async_receive_desc_(NULL), + async_send_desc_(NULL), + anchor_(new nacl::WeakRefAnchor()), + rev_interface_(new PluginReverseInterface(anchor_, plugin, + init_done_cb)) { + NaClSrpcChannelInitialize(&command_channel_); +} + +bool ServiceRuntime::InitCommunication(nacl::DescWrapper* nacl_desc, + ErrorInfo* error_info) { + PLUGIN_PRINTF(("ServiceRuntime::InitCommunication" + " (this=%p, subprocess=%p)\n", + static_cast<void*>(this), + static_cast<void*>(subprocess_.get()))); + // Create the command channel to the sel_ldr and load the nexe from nacl_desc. + if (!subprocess_->SetupCommandAndLoad(&command_channel_, nacl_desc)) { + error_info->SetReport(ERROR_SEL_LDR_COMMUNICATION_CMD_CHANNEL, + "ServiceRuntime: command channel creation failed"); + return false; + } + // Hook up the reverse service channel. We are the IMC client, but + // provide SRPC service. + NaClDesc* out_conn_cap; + NaClSrpcResultCodes rpc_result = + NaClSrpcInvokeBySignature(&command_channel_, + "reverse_setup::h", + &out_conn_cap); + + if (NACL_SRPC_RESULT_OK != rpc_result) { + error_info->SetReport(ERROR_SEL_LDR_COMMUNICATION_REV_SETUP, + "ServiceRuntime: reverse setup rpc failed"); + return false; + } + // Get connection capability to service runtime where the IMC + // server/SRPC client is waiting for a rendezvous. + PLUGIN_PRINTF(("ServiceRuntime: got 0x%"NACL_PRIxPTR"\n", + (uintptr_t) out_conn_cap)); + nacl::DescWrapper* conn_cap = plugin_->wrapper_factory()->MakeGenericCleanup( + out_conn_cap); + if (conn_cap == NULL) { + error_info->SetReport(ERROR_SEL_LDR_COMMUNICATION_WRAPPER, + "ServiceRuntime: wrapper allocation failure"); + return false; + } + out_conn_cap = NULL; // ownership passed + reverse_service_ = new nacl::ReverseService(conn_cap, rev_interface_->Ref()); + if (!reverse_service_->Start()) { + error_info->SetReport(ERROR_SEL_LDR_COMMUNICATION_REV_SERVICE, + "ServiceRuntime: starting reverse services failed"); + return false; + } + +#if NACL_WINDOWS && !defined(NACL_STANDALONE) + // Establish the communication for handle passing protocol + struct NaClDesc* desc = NaClHandlePassBrowserGetSocketAddress(); + + DWORD my_pid = GetCurrentProcessId(); + nacl::Handle my_handle = GetCurrentProcess(); + nacl::Handle my_handle_in_selldr; + + if (!DuplicateHandle(GetCurrentProcess(), + my_handle, + subprocess_->child_process(), + &my_handle_in_selldr, + PROCESS_DUP_HANDLE, + FALSE, + 0)) { + error_info->SetReport(ERROR_SEL_LDR_HANDLE_PASSING, + "ServiceRuntime: failed handle passing protocol"); + return false; + } + + rpc_result = + NaClSrpcInvokeBySignature(&command_channel_, + "init_handle_passing:hii:", + desc, + my_pid, + reinterpret_cast<int>(my_handle_in_selldr)); + + if (NACL_SRPC_RESULT_OK != rpc_result) { + error_info->SetReport(ERROR_SEL_LDR_HANDLE_PASSING, + "ServiceRuntime: failed handle passing protocol"); + return false; + } +#endif + // start the module. otherwise we cannot connect for multimedia + // subsystem since that is handled by user-level code (not secure!) + // in libsrpc. + int load_status = -1; + rpc_result = + NaClSrpcInvokeBySignature(&command_channel_, + "start_module::i", + &load_status); + + if (NACL_SRPC_RESULT_OK != rpc_result) { + error_info->SetReport(ERROR_SEL_LDR_START_MODULE, + "ServiceRuntime: could not start nacl module"); + return false; + } + PLUGIN_PRINTF(("ServiceRuntime::InitCommunication (load_status=%d)\n", + load_status)); + plugin_->ReportSelLdrLoadStatus(load_status); + if (LOAD_OK != load_status) { + error_info->SetReport( + ERROR_SEL_LDR_START_STATUS, + NaClErrorString(static_cast<NaClErrorCode>(load_status))); + return false; + } + return true; +} + +bool ServiceRuntime::Start(nacl::DescWrapper* nacl_desc, + ErrorInfo* error_info) { + PLUGIN_PRINTF(("ServiceRuntime::Start (nacl_desc=%p)\n", + reinterpret_cast<void*>(nacl_desc))); + + nacl::scoped_ptr<nacl::SelLdrLauncher> + tmp_subprocess(new(std::nothrow) nacl::SelLdrLauncher()); + if (NULL == tmp_subprocess.get()) { + PLUGIN_PRINTF(("ServiceRuntime::Start (subprocess create failed)\n")); + error_info->SetReport(ERROR_SEL_LDR_CREATE_LAUNCHER, + "ServiceRuntime: failed to create sel_ldr launcher"); + return false; + } + nacl::Handle sockets[3]; + if (!tmp_subprocess->Start(NACL_ARRAY_SIZE(sockets), sockets)) { + PLUGIN_PRINTF(("ServiceRuntime::Start (start failed)\n")); + error_info->SetReport(ERROR_SEL_LDR_LAUNCH, + "ServiceRuntime: failed to start"); + return false; + } + + async_receive_desc_.reset( + plugin()->wrapper_factory()->MakeImcSock(sockets[1])); + async_send_desc_.reset(plugin()->wrapper_factory()->MakeImcSock(sockets[2])); + + subprocess_.reset(tmp_subprocess.release()); + if (!InitCommunication(nacl_desc, error_info)) { + subprocess_.reset(NULL); + return false; + } + + PLUGIN_PRINTF(("ServiceRuntime::Start (return 1)\n")); + return true; +} + +SrpcClient* ServiceRuntime::SetupAppChannel() { + PLUGIN_PRINTF(("ServiceRuntime::SetupAppChannel (subprocess_=%p)\n", + reinterpret_cast<void*>(subprocess_.get()))); + nacl::DescWrapper* connect_desc = subprocess_->socket_addr()->Connect(); + if (NULL == connect_desc) { + PLUGIN_PRINTF(("ServiceRuntime::SetupAppChannel (connect failed)\n")); + return NULL; + } else { + PLUGIN_PRINTF(("ServiceRuntime::SetupAppChannel (conect_desc=%p)\n", + static_cast<void*>(connect_desc))); + SrpcClient* srpc_client = SrpcClient::New(plugin(), connect_desc); + PLUGIN_PRINTF(("ServiceRuntime::SetupAppChannel (srpc_client=%p)\n", + static_cast<void*>(srpc_client))); + return srpc_client; + } +} + +bool ServiceRuntime::Kill() { + return subprocess_->KillChildProcess(); +} + +bool ServiceRuntime::Log(int severity, nacl::string msg) { + NaClSrpcResultCodes rpc_result = + NaClSrpcInvokeBySignature(&command_channel_, + "log:is:", + severity, + strdup(msg.c_str())); + return (NACL_SRPC_RESULT_OK == rpc_result); +} + +void ServiceRuntime::Shutdown() { + if (subprocess_ != NULL) { + Kill(); + } + rev_interface_->ShutDown(); + anchor_->Abandon(); + // Abandon callbacks, tell service threads to quit if they were + // blocked waiting for main thread operations to finish. Note that + // some callbacks must still await their completion event, e.g., + // CallOnMainThread must still wait for the time out, or I/O events + // must finish, so resources associated with pending events cannot + // be deallocated. + + // Note that this does waitpid() to get rid of any zombie subprocess. + subprocess_.reset(NULL); + + NaClSrpcDtor(&command_channel_); + + // subprocess_ killed, but threads waiting on messages from the + // service runtime may not have noticed yet. The low-level + // NaClSimpleRevService code takes care to refcount the data objects + // that it needs, and reverse_service_ is also refcounted. We wait + // for the service threads to get their EOF indications. + if (reverse_service_ != NULL) { + reverse_service_->WaitForServiceThreadsToExit(); + reverse_service_->Unref(); + reverse_service_ = NULL; + } +} + +ServiceRuntime::~ServiceRuntime() { + PLUGIN_PRINTF(("ServiceRuntime::~ServiceRuntime (this=%p)\n", + static_cast<void*>(this))); + // We do this just in case Shutdown() was not called. + subprocess_.reset(NULL); + if (reverse_service_ != NULL) { + reverse_service_->Unref(); + } + + rev_interface_->Unref(); + + anchor_->Unref(); +} + +} // namespace plugin diff --git a/ppapi/native_client/src/trusted/plugin/service_runtime.h b/ppapi/native_client/src/trusted/plugin/service_runtime.h new file mode 100644 index 0000000..51b8c45 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/service_runtime.h @@ -0,0 +1,189 @@ +/* -*- c++ -*- */ +/* + * 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. + */ + +// A class containing information regarding a socket connection to a +// service runtime instance. + +#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_SERVICE_RUNTIME_H_ +#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_SERVICE_RUNTIME_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/include/nacl_string.h" +#include "native_client/src/shared/imc/nacl_imc.h" +#include "native_client/src/shared/platform/nacl_sync.h" +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "native_client/src/trusted/reverse_service/reverse_service.h" +#include "native_client/src/trusted/plugin/utility.h" +#include "native_client/src/trusted/plugin/file_downloader.h" +#include "native_client/src/trusted/desc/nacl_desc_wrapper.h" +#include "native_client/src/trusted/weak_ref/weak_ref.h" + +#include "ppapi/cpp/completion_callback.h" + +namespace nacl { +class DescWrapper; +struct SelLdrLauncher; +} // namespace + +namespace plugin { + +class BrowserInterface; +class ErrorInfo; +class Plugin; +class SrpcClient; +class SrtSocket; +class ScriptableHandle; +class ServiceRuntime; + +// Callback resources are essentially our continuation state. + +struct LogToJavaScriptConsoleResource { + public: + explicit LogToJavaScriptConsoleResource(std::string msg) + : message(msg) {} + std::string message; +}; + +struct OpenManifestEntryResource { + public: + OpenManifestEntryResource(std::string target_url, + int32_t* descp, + ErrorInfo* infop, + bool* portablep, + bool* op_complete) + : url(target_url), + out_desc(descp), + error_info(infop), + is_portable(portablep), + op_complete_ptr(op_complete) {} + std::string url; + int32_t* out_desc; + ErrorInfo* error_info; + bool* is_portable; + bool* op_complete_ptr; +}; + +struct CloseManifestEntryResource { + public: + CloseManifestEntryResource(int32_t desc_to_close, + bool* op_complete, + bool* op_result) + : desc(desc_to_close), + op_complete_ptr(op_complete), + op_result_ptr(op_result) {} + + int32_t desc; + bool* op_complete_ptr; + bool* op_result_ptr; +}; + +// Do not invoke from the main thread, since the main methods will +// invoke CallOnMainThread and then wait on a condvar for the task to +// complete: if invoked from the main thread, the main method not +// returning (and thus unblocking the main thread) means that the +// main-thread continuation methods will never get called, and thus +// we'd get a deadlock. +class PluginReverseInterface: public nacl::ReverseInterface { + public: + PluginReverseInterface(nacl::WeakRefAnchor* anchor, + Plugin* plugin, + pp::CompletionCallback init_done_cb); + + virtual ~PluginReverseInterface(); + + void ShutDown(); + + virtual void Log(nacl::string message); + + virtual void StartupInitializationComplete(); + + virtual bool EnumerateManifestKeys(std::set<nacl::string>* out_keys); + + virtual bool OpenManifestEntry(nacl::string url_key, int32_t* out_desc); + + virtual bool CloseManifestEntry(int32_t desc); + + protected: + virtual void Log_MainThreadContinuation(LogToJavaScriptConsoleResource* p, + int32_t err); + + virtual void OpenManifestEntry_MainThreadContinuation( + OpenManifestEntryResource* p, + int32_t err); + + virtual void StreamAsFile_MainThreadContinuation( + OpenManifestEntryResource* p, + int32_t result); + + virtual void CloseManifestEntry_MainThreadContinuation( + CloseManifestEntryResource* cls, + int32_t err); + + private: + nacl::WeakRefAnchor* anchor_; // holds a ref + Plugin* plugin_; // value may be copied, but should be used only in + // main thread in WeakRef-protected callbacks. + NaClMutex mu_; + NaClCondVar cv_; + bool shutting_down_; + + pp::CompletionCallback init_done_cb_; +}; + +// ServiceRuntime abstracts a NativeClient sel_ldr instance. +class ServiceRuntime { + public: + // TODO(sehr): This class should also implement factory methods, using the + // Start method below. + ServiceRuntime(Plugin* plugin, + pp::CompletionCallback init_done_cb); + // The destructor terminates the sel_ldr process. + ~ServiceRuntime(); + + // Spawn a sel_ldr instance and establish an SrpcClient to it. The nexe + // to be started is passed through |nacl_file_desc|. On success, returns + // true. On failure, returns false and |error_string| is set to something + // describing the error. + bool Start(nacl::DescWrapper* nacl_file_desc, ErrorInfo* error_info); + + // Starts the application channel to the nexe. + SrpcClient* SetupAppChannel(); + + bool Kill(); + bool Log(int severity, nacl::string msg); + Plugin* plugin() const { return plugin_; } + void Shutdown(); + + nacl::DescWrapper* async_receive_desc() { return async_receive_desc_.get(); } + nacl::DescWrapper* async_send_desc() { return async_send_desc_.get(); } + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(ServiceRuntime); + bool InitCommunication(nacl::DescWrapper* shm, ErrorInfo* error_info); + + NaClSrpcChannel command_channel_; + Plugin* plugin_; + BrowserInterface* browser_interface_; + nacl::ReverseService* reverse_service_; + nacl::scoped_ptr<nacl::SelLdrLauncher> subprocess_; + + // We need two IMC sockets rather than one because IMC sockets are + // not full-duplex on Windows. + // See http://code.google.com/p/nativeclient/issues/detail?id=690. + // TODO(mseaborn): We should not have to work around this. + nacl::scoped_ptr<nacl::DescWrapper> async_receive_desc_; + nacl::scoped_ptr<nacl::DescWrapper> async_send_desc_; + + nacl::WeakRefAnchor* anchor_; + + PluginReverseInterface* rev_interface_; +}; + +} // namespace plugin + +#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_SERVICE_RUNTIME_H_ diff --git a/ppapi/native_client/src/trusted/plugin/srpc_client.cc b/ppapi/native_client/src/trusted/plugin/srpc_client.cc new file mode 100644 index 0000000..7eed2ed --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/srpc_client.cc @@ -0,0 +1,165 @@ +/* + * 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 <string.h> + +#include <map> + +#include "native_client/src/shared/platform/nacl_log.h" +#include "native_client/src/trusted/plugin/browser_interface.h" +#include "native_client/src/trusted/plugin/desc_based_handle.h" +#include "native_client/src/trusted/plugin/plugin.h" +#include "native_client/src/trusted/plugin/scriptable_handle.h" +#include "native_client/src/trusted/plugin/srpc_client.h" +#include "native_client/src/trusted/plugin/utility.h" + +namespace plugin { + +SrpcClient::SrpcClient() + : srpc_channel_initialised_(false), + browser_interface_(NULL) { + PLUGIN_PRINTF(("SrpcClient::SrpcClient (this=%p)\n", + static_cast<void*>(this))); + NaClSrpcChannelInitialize(&srpc_channel_); +} + +SrpcClient* SrpcClient::New(Plugin* plugin, nacl::DescWrapper* wrapper) { + nacl::scoped_ptr<SrpcClient> srpc_client(new SrpcClient()); + if (!srpc_client->Init(plugin->browser_interface(), wrapper)) { + PLUGIN_PRINTF(("SrpcClient::New (SrpcClient::Init failed)\n")); + return NULL; + } + return srpc_client.release(); +} + +bool SrpcClient::Init(BrowserInterface* browser_interface, + nacl::DescWrapper* wrapper) { + PLUGIN_PRINTF(("SrpcClient::Init (this=%p, browser_interface=%p, wrapper=%p)" + "\n", static_cast<void*>(this), + static_cast<void*>(browser_interface), + static_cast<void*>(wrapper))); + // Open the channel to pass RPC information back and forth + if (!NaClSrpcClientCtor(&srpc_channel_, wrapper->desc())) { + return false; + } + srpc_channel_initialised_ = true; + browser_interface_ = browser_interface; + PLUGIN_PRINTF(("SrpcClient::Init (Ctor worked)\n")); + // Record the method names in a convenient way for later dispatches. + GetMethods(); + PLUGIN_PRINTF(("SrpcClient::Init (GetMethods worked)\n")); + return true; +} + +SrpcClient::~SrpcClient() { + PLUGIN_PRINTF(("SrpcClient::~SrpcClient (this=%p, has_srpc_channel=%d)\n", + static_cast<void*>(this), srpc_channel_initialised_)); + // And delete the connection. + if (srpc_channel_initialised_) { + PLUGIN_PRINTF(("SrpcClient::~SrpcClient (destroying srpc_channel)\n")); + NaClSrpcDtor(&srpc_channel_); + } + for (Methods::iterator iter = methods_.begin(); + iter != methods_.end(); + ++iter) { + delete iter->second; + } + PLUGIN_PRINTF(("SrpcClient::~SrpcClient (return)\n")); +} + +bool SrpcClient::StartJSObjectProxy(Plugin* plugin, + ErrorInfo *error_info) { + // Start up PPAPI interaction if the plugin determines that the + // requisite methods are exported. + return plugin->StartProxiedExecution(&srpc_channel_, error_info); +} + +void SrpcClient::GetMethods() { + PLUGIN_PRINTF(("SrpcClient::GetMethods (this=%p)\n", + static_cast<void*>(this))); + if (NULL == srpc_channel_.client) { + return; + } + uint32_t method_count = NaClSrpcServiceMethodCount(srpc_channel_.client); + // Intern the methods into a mapping from identifiers to MethodInfo. + for (uint32_t i = 0; i < method_count; ++i) { + int retval; + const char* name; + const char* input_types; + const char* output_types; + + retval = NaClSrpcServiceMethodNameAndTypes(srpc_channel_.client, + i, + &name, + &input_types, + &output_types); + if (!IsValidIdentifierString(name, NULL)) { + // If name is not an ECMAScript identifier, do not enter it into the + // methods_ table. + continue; + } + uintptr_t ident = browser_interface_->StringToIdentifier(name); + MethodInfo* method_info = + new MethodInfo(NULL, name, input_types, output_types, i); + if (NULL == method_info) { + return; + } + // Install in the map only if successfully read. + methods_[ident] = method_info; + } +} + +bool SrpcClient::HasMethod(uintptr_t method_id) { + bool has_method = (NULL != methods_[method_id]); + PLUGIN_PRINTF(("SrpcClient::HasMethod (this=%p, return %d)\n", + static_cast<void*>(this), has_method)); + return has_method; +} + +bool SrpcClient::InitParams(uintptr_t method_id, SrpcParams* params) { + MethodInfo* method_info = methods_[method_id]; + if (method_info) { + return params->Init(method_info->ins(), method_info->outs()); + } + return false; +} + +bool SrpcClient::Invoke(uintptr_t method_id, + SrpcParams* params) { + // It would be better if we could set the exception on each detailed failure + // case. However, there are calls to Invoke from within the plugin itself, + // and these could leave residual exceptions pending. This seems to be + // happening specifically with hard_shutdowns. + PLUGIN_PRINTF(("SrpcClient::Invoke (this=%p, method_name='%s', params=%p)\n", + static_cast<void*>(this), + browser_interface_->IdentifierToString(method_id).c_str(), + static_cast<void*>(params))); + + // Ensure Invoke was called with an identifier that had a binding. + if (NULL == methods_[method_id]) { + PLUGIN_PRINTF(("SrpcClient::Invoke (ident not in methods_)\n")); + return false; + } + + PLUGIN_PRINTF(("SrpcClient::Invoke (sending the rpc)\n")); + // Call the method + NaClSrpcError err = NaClSrpcInvokeV(&srpc_channel_, + methods_[method_id]->index(), + params->ins(), + params->outs()); + PLUGIN_PRINTF(("SrpcClient::Invoke (response=%d)\n", err)); + if (NACL_SRPC_RESULT_OK != err) { + PLUGIN_PRINTF(("SrpcClient::Invoke (err='%s', return 0)\n", + NaClSrpcErrorString(err))); + return false; + } + + PLUGIN_PRINTF(("SrpcClient::Invoke (return 1)\n")); + return true; +} + +} // namespace plugin diff --git a/ppapi/native_client/src/trusted/plugin/srpc_client.h b/ppapi/native_client/src/trusted/plugin/srpc_client.h new file mode 100644 index 0000000..7fc8ee2 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/srpc_client.h @@ -0,0 +1,64 @@ +/* + * 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. + */ + +// A representation of an SRPC connection. These can be either to the +// service runtime or to untrusted NaCl threads. + +#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_SRPC_CLIENT_H_ +#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_SRPC_CLIENT_H_ + +#include <map> +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/nacl_string.h" +#include "native_client/src/trusted/plugin/utility.h" +#include "native_client/src/shared/srpc/nacl_srpc.h" + +namespace nacl { +class DescWrapper; +} // namespace nacl + +namespace plugin { + +class BrowserInterface; +class ErrorInfo; +class MethodInfo; +class Plugin; +class SrpcParams; + +// SrpcClient represents an SRPC connection to a client. +class SrpcClient { + public: + // Factory method for creating SrpcClients. + static SrpcClient* New(Plugin* plugin, nacl::DescWrapper* wrapper); + + // Init is passed a DescWrapper. The SrpcClient performs service + // discovery and provides the interface for future rpcs. + bool Init(BrowserInterface* browser_interface, nacl::DescWrapper* socket); + + // The destructor closes the connection to sel_ldr. + ~SrpcClient(); + + bool StartJSObjectProxy(Plugin* plugin, ErrorInfo* error_info); + // Test whether the SRPC service has a given method. + bool HasMethod(uintptr_t method_id); + // Invoke an SRPC method. + bool Invoke(uintptr_t method_id, SrpcParams* params); + bool InitParams(uintptr_t method_id, SrpcParams* params); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(SrpcClient); + SrpcClient(); + void GetMethods(); + typedef std::map<uintptr_t, MethodInfo*> Methods; + Methods methods_; + NaClSrpcChannel srpc_channel_; + bool srpc_channel_initialised_; + BrowserInterface* browser_interface_; +}; + +} // namespace plugin + +#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_SRPC_CLIENT_H_ diff --git a/ppapi/native_client/src/trusted/plugin/string_encoding.cc b/ppapi/native_client/src/trusted/plugin/string_encoding.cc new file mode 100644 index 0000000..f98cd6b --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/string_encoding.cc @@ -0,0 +1,100 @@ +/* + * 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/include/nacl_platform.h" +#include "native_client/src/trusted/plugin/string_encoding.h" + + +namespace plugin { + +// PPAPI requires us to encode byte strings as UTF-8. Unfortunately +// this is rather inefficient, in terms of both space and time. + +bool ByteStringAsUTF8(const char* input, size_t input_byte_count, + char** result, size_t* result_byte_count) { + // UTF-8 encoding may result in a 2x size increase at the most. + // TODO(mseaborn): We could do a pre-scan to get the real size. + // If we wanted to be faster, we could do a word-by-word pre-scan + // to check for top-bit-set characters. + size_t max_output_size = input_byte_count * 2; + // We include a null terminator for convenience. + char* output = reinterpret_cast<char*>(malloc(max_output_size + 1)); + if (output == NULL) { + return false; + } + char* dest_ptr = output; + for (size_t i = 0; i < input_byte_count; i++) { + unsigned char ch = input[i]; + if (ch < 128) { + // Code results in a one byte encoding. + *dest_ptr++ = ch; + } else { + // Code results in a two byte encoding. + *dest_ptr++ = 0xc0 | (ch >> 6); /* Top 2 bits */ + *dest_ptr++ = 0x80 | (ch & 0x3f); /* Bottom 6 bits */ + } + } + *dest_ptr = 0; + *result = output; + *result_byte_count = dest_ptr - output; + return true; +} + +bool ByteStringFromUTF8(const char* input, size_t input_byte_count, + char** result, size_t* result_byte_count) { + // The output cannot be larger than the input. + char* output = reinterpret_cast<char*>(malloc(input_byte_count + 1)); + if (output == NULL) { + return NULL; + } + char* dest_ptr = output; + size_t i; + for (i = 0; i < input_byte_count; ) { + unsigned char ch = input[i]; + if ((ch & 0x80) == 0) { + // One byte encoding. + *dest_ptr++ = ch; + i++; + } else { + if (i == input_byte_count - 1) { + // Invalid UTF-8: incomplete sequence. + goto fail; + } + // Check that this is a two byte encoding. + // The first character must contain 110xxxxxb and the + // second must contain 10xxxxxxb. + unsigned char ch2 = input[i + 1]; + if ((ch & 0xe0) != 0xc0) { + // >=2 byte encoding. + goto fail; + } + if ((ch2 & 0xc0) != 0x80) { + // Invalid UTF-8. + goto fail; + } + uint32_t value = (((uint32_t) ch & 0x1f) << 6) | ((uint32_t) ch2 & 0x3f); + if (value < 128) { + // Invalid UTF-8: overly long encoding. + goto fail; + } + if (value >= 0x100) { + // Overly large character. Will not fit into a byte. + goto fail; + } + *dest_ptr++ = value; + i += 2; + } + } + *dest_ptr = 0; + *result = output; + *result_byte_count = dest_ptr - output; + return true; + fail: + free(output); + return false; +} + +} // namespace plugin diff --git a/ppapi/native_client/src/trusted/plugin/string_encoding.h b/ppapi/native_client/src/trusted/plugin/string_encoding.h new file mode 100644 index 0000000..35ed1e5 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/string_encoding.h @@ -0,0 +1,21 @@ +/* + * Copyright 2010 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. + */ + +#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_STRING_ENCODING_H_ +#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_STRING_ENCODING_H_ + +#include <stdlib.h> + +namespace plugin { + +bool ByteStringAsUTF8(const char* input, size_t input_byte_count, + char** result, size_t* result_byte_count); +bool ByteStringFromUTF8(const char* input, size_t input_byte_count, + char** result, size_t* result_byte_count); + +} + +#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_STRING_ENCODING_H_ diff --git a/ppapi/native_client/src/trusted/plugin/string_encoding_test.cc b/ppapi/native_client/src/trusted/plugin/string_encoding_test.cc new file mode 100644 index 0000000..8f25bb3 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/string_encoding_test.cc @@ -0,0 +1,55 @@ +/* + * Copyright 2010 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 <string.h> + +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/src/trusted/plugin/string_encoding.h" + + +int main() { + const char* input; + char* output; + size_t output_size; + + // Valid input. + + input = "Hello world, \x80 and \xff"; + CHECK(plugin::ByteStringAsUTF8(input, strlen(input), &output, &output_size)); + CHECK(strcmp(output, "Hello world, \xc2\x80 and \xc3\xbf") == 0); + CHECK(plugin::ByteStringFromUTF8(output, output_size, &output, &output_size)); + CHECK(strcmp(output, "Hello world, \x80 and \xff") == 0); + + // Valid UTF-8, but chars too big. + + // Three-byte sequence + // This encodes \u1000 + input = "\xe1\x80\x80"; + CHECK(!plugin::ByteStringFromUTF8(input, strlen(input), + &output, &output_size)); + // This encodes \u0100 + input = "\xc4\x80"; + CHECK(!plugin::ByteStringFromUTF8(input, strlen(input), + &output, &output_size)); + + // Invalid UTF-8. + + // Incomplete sequence + input = "\xc2"; + CHECK(!plugin::ByteStringFromUTF8(input, strlen(input), + &output, &output_size)); + // Subsequent byte is wrong + input = "\xc2 "; + CHECK(!plugin::ByteStringFromUTF8(input, strlen(input), + &output, &output_size)); + // Over long encoding + // This is a non-canonical encoding for \x00 + input = "\xc0\x80"; + CHECK(!plugin::ByteStringFromUTF8(input, strlen(input), + &output, &output_size)); + + return 0; +} diff --git a/ppapi/native_client/src/trusted/plugin/utility.cc b/ppapi/native_client/src/trusted/plugin/utility.cc new file mode 100644 index 0000000..85a5a64 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/utility.cc @@ -0,0 +1,103 @@ +/* + * 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 <stdarg.h> +#include <stdlib.h> +#include <string.h> + +#include "native_client/src/trusted/plugin/utility.h" + +namespace plugin { + +int gNaClPluginDebugPrintEnabled = -1; +FILE* gNaClPluginLogFile = NULL; + +/* + * Prints formatted message to the log. + */ +int NaClPluginPrintLog(const char *format, ...) { + if (NULL == gNaClPluginLogFile) { + return 0; + } + va_list arg; + int done; + va_start(arg, format); + done = vfprintf(gNaClPluginLogFile, format, arg); + va_end(arg); + fflush(gNaClPluginLogFile); + return done; +} + +/* + * Opens file where plugin log should be written. The file name is + * taken from NACL_PLUGIN_LOG environment variable. + * If environment variable doesn't exist or file can't be opened, + * the function returns stdout. + */ +FILE* NaClPluginLogFileEnv() { + char* file = getenv("NACL_PLUGIN_LOG"); + if (NULL != file) { + FILE* log_file = fopen(file, "w+"); + if (NULL == log_file) { + return stdout; + } + return log_file; + } + return stdout; +} + +/* + * Currently looks for presence of NACL_PLUGIN_DEBUG and returns + * 0 if absent and 1 if present. In the future we may include notions + * of verbosity level. + */ +int NaClPluginDebugPrintCheckEnv() { + char* env = getenv("NACL_PLUGIN_DEBUG"); + return (NULL != env); +} + +bool IsValidIdentifierString(const char* strval, uint32_t* length) { + // This function is supposed to recognize valid ECMAScript identifiers, + // as described in + // http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf + // It is currently restricted to only the ASCII subset. + // TODO(sehr): Recognize the full Unicode formulation of identifiers. + // TODO(sehr): Make this table-driven if efficiency becomes a problem. + if (NULL != length) { + *length = 0; + } + if (NULL == strval) { + return false; + } + static const char* kValidFirstChars = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz$_"; + static const char* kValidOtherChars = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz$_" + "0123456789"; + if (NULL == strchr(kValidFirstChars, strval[0])) { + return false; + } + uint32_t pos; + for (pos = 1; ; ++pos) { + if (0 == pos) { + // Unsigned overflow. + return false; + } + int c = strval[pos]; + if (0 == c) { + break; + } + if (NULL == strchr(kValidOtherChars, c)) { + return false; + } + } + if (NULL != length) { + *length = pos; + } + return true; +} + +} // namespace plugin diff --git a/ppapi/native_client/src/trusted/plugin/utility.h b/ppapi/native_client/src/trusted/plugin/utility.h new file mode 100644 index 0000000..efd4e75 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/utility.h @@ -0,0 +1,54 @@ +/* + * 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. + */ + +// A collection of debugging related interfaces. + +#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_UTILITY_H_ +#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_UTILITY_H_ + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/platform/nacl_threads.h" + +#define SRPC_PLUGIN_DEBUG 1 + +namespace plugin { + +// Tests that a string is a valid JavaScript identifier. According to the +// ECMAScript spec, this should be done in terms of unicode character +// categories. For now, we are simply limiting identifiers to the ASCII +// subset of that spec. If successful, it returns the length of the +// identifier in the location pointed to by length (if it is not NULL). +// TODO(sehr): add Unicode identifier support. +bool IsValidIdentifierString(const char* strval, uint32_t* length); + +// Debugging print utility +extern int gNaClPluginDebugPrintEnabled; +extern FILE* gNaClPluginLogFile; +extern int NaClPluginPrintLog(const char *format, ...); +extern int NaClPluginDebugPrintCheckEnv(); +extern FILE* NaClPluginLogFileEnv(); +#if SRPC_PLUGIN_DEBUG +# define PLUGIN_PRINTF(args) do { \ + if (-1 == ::plugin::gNaClPluginDebugPrintEnabled) { \ + ::plugin::gNaClPluginDebugPrintEnabled = \ + ::plugin::NaClPluginDebugPrintCheckEnv(); \ + ::plugin::gNaClPluginLogFile = ::plugin::NaClPluginLogFileEnv();\ + } \ + if (0 != ::plugin::gNaClPluginDebugPrintEnabled) { \ + ::plugin::NaClPluginPrintLog("%08"NACL_PRIx32": ", \ + NaClThreadId()); \ + ::plugin::NaClPluginPrintLog args; \ + } \ + } while (0) +#else +# define PLUGIN_PRINTF(args) do { if (0) { printf args; } } while (0) +/* allows DCE but compiler can still do format string checks */ +#endif + +} // namespace plugin + +#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_UTILITY_H_ diff --git a/ppapi/native_client/src/trusted/plugin/var_utils.cc b/ppapi/native_client/src/trusted/plugin/var_utils.cc new file mode 100644 index 0000000..027affc --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/var_utils.cc @@ -0,0 +1,417 @@ +// 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 <assert.h> + +#include "native_client/src/trusted/plugin/var_utils.h" + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/nacl_string.h" +#include "native_client/src/include/portability_io.h" +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/src/trusted/desc/nacl_desc_wrapper.h" +#include "native_client/src/trusted/plugin/array_ppapi.h" +#include "native_client/src/trusted/plugin/desc_based_handle.h" +#include "native_client/src/trusted/plugin/scriptable_handle.h" +#include "native_client/src/trusted/plugin/utility.h" + +#include "ppapi/cpp/dev/scriptable_object_deprecated.h" + +namespace plugin { + + +// In JavaScript, foo[1] is equivalent to foo["1"], so map both indexed and +// string names to a string. +nacl::string NameAsString(const pp::Var& name) { + if (name.is_string()) + return name.AsString(); + assert(name.is_int()); + nacl::stringstream namestream; + namestream << name.AsInt(); + return namestream.str(); +} + + +//----------------------------------------------------------------------------- +// Translation from pp::Var to NaClSrpcArg +//----------------------------------------------------------------------------- + +namespace { + +// Sets |array_length| and allocate |array_data| based on the length +// represented by |var|. Sets |exception| on error. +template<typename T> void PPVarToAllocateArray(const pp::Var& var, + nacl_abi_size_t* array_length, + T** array_data, + pp::Var* exception) { + // Initialize result values for error cases. + *array_length = 0; + *array_data = NULL; + + if (!var.is_number()) { + *exception = "incompatible argument: unable to get array length"; + return; + } + // AsInt will work if var is int or double. + size_t length = var.AsInt(); + + // Check for overflow on size multiplication and IMC array size limit. + if ((length > SIZE_T_MAX / sizeof(T)) || + (length * sizeof(T) > NACL_ABI_IMC_USER_BYTES_MAX)) { + *exception = "incompatible argument: array length is too long"; + return; + } + + *array_length = static_cast<nacl_abi_size_t>(length); + *array_data = reinterpret_cast<T*>(malloc(sizeof(T) * length)); + if (array_data == NULL) { + *exception = "incompatible argument: internal error"; + } +} + + +// Translates |var| into |array_length| and |array_data| for type |type|. +// Sets |exception| on error. +template<typename T> void PPVarToArray(const pp::Var& var, + nacl_abi_size_t* array_length, + T** array_data, + pp::Var* exception) { + if (!var.is_object()) { + *exception = "incompatible argument: type is not array"; + return; + } + pp::VarPrivate var_private(var); + + pp::Var length_var = var_private.GetProperty(pp::Var("length"), exception); + PLUGIN_PRINTF((" PPVarToArray (length=%s)\n", + length_var.DebugString().c_str())); + PPVarToAllocateArray(length_var, array_length, array_data, exception); + if (!exception->is_undefined()) { + return; + } + + for (size_t i = 0; i < *array_length; ++i) { + int32_t index = nacl::assert_cast<int32_t>(i); + pp::Var element = var_private.GetProperty(pp::Var(index), exception); + PLUGIN_PRINTF((" PPVarToArray (array[%d]=%s)\n", + index, element.DebugString().c_str())); + if (!exception->is_undefined()) { + break; + } + if (!element.is_number()) { + *exception = "incompatible argument: non-numeric element type"; + break; + } + if (element.is_int()) { + (*array_data)[i] = static_cast<T>(element.AsInt()); + } else if (element.is_double()) { + (*array_data)[i] = static_cast<T>(element.AsDouble()); + } else { + NACL_NOTREACHED(); + } + } + if (!exception->is_undefined()) { + free(array_data); + *array_length = 0; + *array_data = NULL; + } +} + + +// Returns the address of |var| if var is an object. Sets |exception| on error. +// |var| was passed in from SRPC input marshalling. It is guaranteed to be +// alive until the SRPC method is dispatched to. +pp::Var* PPVarToObjectVar(const pp::Var& var, pp::Var* exception) { + if (!var.is_object()) { + *exception = "incompatible argument: type is not object"; + return NULL; + } + return const_cast<pp::Var*>(&var); +} + + +// Returns NaClDesc* corresponding to |var|. Sets |exception| on error. +NaClDesc* PPVarToNaClDesc(const pp::Var& var, pp::Var* exception) { + if (!var.is_object()) { + *exception = "incompatible argument: type is not object"; + return NULL; + } + pp::VarPrivate var_private(var); + pp::deprecated::ScriptableObject* scriptable_object = + var_private.AsScriptableObject(); + if (scriptable_object == NULL) { + *exception = "incompatible argument: type is not scriptable object"; + return NULL; + } + ScriptableHandle* scriptable_handle = + static_cast<ScriptableHandle*>(scriptable_object); + if (!ScriptableHandle::is_valid(scriptable_handle)) { + *exception = "incompatible argument: not a valid scriptable handle"; + return NULL; + } + NaClDesc* nacl_desc = scriptable_handle->desc_handle()->desc(); + if (nacl_desc == NULL) { + *exception = "incompatible argument: not a handle object"; + return NULL; + } + return nacl_desc; +} + + +// Allocates and returns a pointer to string corresponding to |var|. +// Sets |exception| on error. +char* PPVarToString(const pp::Var& var, pp::Var* exception) { + if (!var.is_string()) { + *exception = "incompatible argument: type is not string"; + return NULL; + } + + nacl::string var_as_string = var.AsString(); + size_t size = var_as_string.size() + 1; // + \0 + char* string_as_chars = reinterpret_cast<char*>(malloc(size)); + if (string_as_chars == NULL) { + *exception = "incompatible argument: internal error"; + return NULL; + } + + memcpy(string_as_chars, var_as_string.c_str(), size); + return string_as_chars; +} + + +// Returns a number corresponding to |var|. JavaScript might mix int and +// double types, so use them interchangeably. Sets |exception| on error. +template<typename T> T PPVarToNumber(const pp::Var& var, pp::Var* exception) { + T result = 0; + if (!var.is_number()) + *exception = "incompatible argument: type is not numeric"; + else if (var.is_double()) + result = static_cast<T>(var.AsDouble()); + else if (var.is_int()) + result = static_cast<T>(var.AsInt()); + return result; +} + +} // namespace + + +// Allocates |arg| of the array length represented by |var|. No-op for scalars. +// Sets |exception| and returns false on error. +bool PPVarToAllocateNaClSrpcArg(const pp::Var& var, + NaClSrpcArg* arg, pp::Var* exception) { + PLUGIN_PRINTF((" PPVarToAllocateNaClSrpcArg (var=%s, arg->tag='%c')\n", + var.DebugString().c_str(), arg->tag)); + switch (arg->tag) { + case NACL_SRPC_ARG_TYPE_BOOL: + case NACL_SRPC_ARG_TYPE_DOUBLE: + case NACL_SRPC_ARG_TYPE_INT: + case NACL_SRPC_ARG_TYPE_LONG: + case NACL_SRPC_ARG_TYPE_STRING: + case NACL_SRPC_ARG_TYPE_HANDLE: + case NACL_SRPC_ARG_TYPE_OBJECT: + break; // nothing to do + case NACL_SRPC_ARG_TYPE_CHAR_ARRAY: + PPVarToAllocateArray(var, &arg->u.count, &arg->arrays.carr, exception); + break; + case NACL_SRPC_ARG_TYPE_DOUBLE_ARRAY: + PPVarToAllocateArray(var, &arg->u.count, &arg->arrays.darr, exception); + break; + case NACL_SRPC_ARG_TYPE_INT_ARRAY: + PPVarToAllocateArray(var, &arg->u.count, &arg->arrays.iarr, exception); + break; + case NACL_SRPC_ARG_TYPE_LONG_ARRAY: + PPVarToAllocateArray(var, &arg->u.count, &arg->arrays.larr, exception); + break; + case NACL_SRPC_ARG_TYPE_VARIANT_ARRAY: + case NACL_SRPC_ARG_TYPE_INVALID: + default: + *exception = "variant array and invalid type arguments are not supported"; + } + PLUGIN_PRINTF((" PPVarToAllocateNaClSrpcArg (return exception=%s)\n", + exception->DebugString().c_str())); + return exception->is_undefined(); +} + + +// Translates |var| into |arg|. Returns false and sets exception on error. +bool PPVarToNaClSrpcArg(const pp::Var& var, + NaClSrpcArg* arg, pp::Var* exception) { + PLUGIN_PRINTF((" PPVarToNaClSrpcArg (var=%s, arg->tag='%c')\n", + var.DebugString().c_str(), arg->tag)); + switch (arg->tag) { + case NACL_SRPC_ARG_TYPE_BOOL: + if (!var.is_bool()) + *exception = "incompatible argument: type is not bool"; + else + arg->u.bval = var.AsBool(); + break; + case NACL_SRPC_ARG_TYPE_DOUBLE: + arg->u.dval = PPVarToNumber<double>(var, exception); + break; + case NACL_SRPC_ARG_TYPE_INT: + arg->u.ival = PPVarToNumber<int32_t>(var, exception); + break; + case NACL_SRPC_ARG_TYPE_LONG: + arg->u.lval = PPVarToNumber<int64_t>(var, exception); + break; + case NACL_SRPC_ARG_TYPE_STRING: + arg->arrays.str = PPVarToString(var, exception); + break; + case NACL_SRPC_ARG_TYPE_CHAR_ARRAY: + PPVarToArray(var, &arg->u.count, &arg->arrays.carr, exception); + break; + case NACL_SRPC_ARG_TYPE_DOUBLE_ARRAY: + PPVarToArray(var, &arg->u.count, &arg->arrays.darr, exception); + break; + case NACL_SRPC_ARG_TYPE_INT_ARRAY: + PPVarToArray(var, &arg->u.count, &arg->arrays.iarr, exception); + break; + case NACL_SRPC_ARG_TYPE_LONG_ARRAY: + PPVarToArray(var, &arg->u.count, &arg->arrays.larr, exception); + break; + case NACL_SRPC_ARG_TYPE_HANDLE: + arg->u.hval = reinterpret_cast<NaClSrpcImcDescType>( + PPVarToNaClDesc(var, exception)); + break; + case NACL_SRPC_ARG_TYPE_OBJECT: + arg->arrays.oval = reinterpret_cast<void*>( + PPVarToObjectVar(var, exception)); + break; + case NACL_SRPC_ARG_TYPE_VARIANT_ARRAY: + case NACL_SRPC_ARG_TYPE_INVALID: + default: + *exception = "variant array and invalid type arguments are not supported"; + } + PLUGIN_PRINTF((" PPVarToNaClSrpcArg (return exception=%s)\n", + exception->DebugString().c_str())); + return exception->is_undefined(); +} + + +//----------------------------------------------------------------------------- +// Translation NaClSrpcArg to pp::Var +//----------------------------------------------------------------------------- + +namespace { + +// PPAPI does not have a 64-bit integer Var type. +// To make the array construction below work, we define a set of overloaded +// functions to convert an array element to a pp::Var. +template<typename T> pp::Var ArrayElementToPPVar(T array_element) { + return pp::Var(array_element); +} + +// One overload is specialized, and it truncates, losing precision of course. +pp::Var ArrayElementToPPVar(int64_t array_element) { + return pp::Var(static_cast<int32_t>(array_element)); +} + +// Return a pp::Var constructed from |array_data|. Sets |exception| on error. +template<typename T> pp::Var ArrayToPPVar(T* array_data, + nacl_abi_size_t array_length, + Plugin* plugin, + pp::Var* exception) { + ArrayPpapi* array = new(std::nothrow) ArrayPpapi(plugin); + if (array == NULL) { + *exception = "incompatible argument: internal error"; + return pp::Var(); + } + + for (size_t i = 0; i < array_length; ++i) { + int32_t index = static_cast<int32_t>(i); + array->SetProperty(pp::Var(index), + ArrayElementToPPVar(array_data[i]), + exception); + } + return pp::VarPrivate(plugin, array); +} + + +// Returns a pp::Var corresponding to |desc| or void. Sets |exception| on error. +pp::Var NaClDescToPPVar(NaClDesc* desc, Plugin* plugin, pp::Var* exception) { + nacl::DescWrapper* wrapper = plugin->wrapper_factory()->MakeGeneric(desc); + + DescBasedHandle* desc_handle = DescBasedHandle::New(wrapper); + + pp::deprecated::ScriptableObject* object = + ScriptableHandle::NewDescHandle(desc_handle); + if (object == NULL) { + *exception = "incompatible argument: failed to create handle var"; + return pp::Var(); + } + return pp::VarPrivate(plugin, object); +} + + +// Returns a pp::Var corresponding to |obj|. Only predeclared plugin methods +// can return objects and they only return a ScriptableHandle that is actually +// a ScriptableHandle. +pp::Var ObjectToPPVar(void* obj) { + ScriptableHandle* handle = reinterpret_cast<ScriptableHandle*>(obj); + // This confirms that this this is indeed a valid SriptableHandle that was + // created by us. In theory, a predeclared method could receive and return + // an opaque JavaScript object that is not a ScriptableHandle. But we don't + // have methods like this at the time. If one ever creates such a method, + // this CHECK will fail and remind the author to update this code to handle + // arbitrary objects. + CHECK(ScriptableHandle::is_valid(handle)); + if (handle->var() != NULL) + return *handle->var(); // make a copy + + return pp::VarPrivate(handle->plugin(), handle); +} + +} // namespace + +// Returns a pp::Var corresponding to |arg| or void. Sets |exception| on error. +pp::Var NaClSrpcArgToPPVar(const NaClSrpcArg* arg, Plugin* plugin, + pp::Var* exception) { + PLUGIN_PRINTF((" NaClSrpcArgToPPVar (arg->tag='%c')\n", arg->tag)); + pp::Var var; + switch (arg->tag) { + case NACL_SRPC_ARG_TYPE_BOOL: + var = pp::Var(arg->u.bval != 0); + break; + case NACL_SRPC_ARG_TYPE_DOUBLE: + var = pp::Var(arg->u.dval); + break; + case NACL_SRPC_ARG_TYPE_INT: + var = pp::Var(arg->u.ival); + break; + case NACL_SRPC_ARG_TYPE_LONG: + // PPAPI does not have a 64-bit integral type. Downcast. + var = pp::Var(static_cast<int32_t>(arg->u.lval)); + break; + case NACL_SRPC_ARG_TYPE_STRING: + var = pp::Var(arg->arrays.str); + break; + case NACL_SRPC_ARG_TYPE_CHAR_ARRAY: + var = ArrayToPPVar(arg->arrays.carr, arg->u.count, plugin, exception); + break; + case NACL_SRPC_ARG_TYPE_DOUBLE_ARRAY: + var = ArrayToPPVar(arg->arrays.darr, arg->u.count, plugin, exception); + break; + case NACL_SRPC_ARG_TYPE_INT_ARRAY: + var = ArrayToPPVar(arg->arrays.iarr, arg->u.count, plugin, exception); + break; + case NACL_SRPC_ARG_TYPE_LONG_ARRAY: + var = ArrayToPPVar(arg->arrays.larr, arg->u.count, plugin, exception); + break; + case NACL_SRPC_ARG_TYPE_HANDLE: + var = NaClDescToPPVar(arg->u.hval, plugin, exception); + break; + case NACL_SRPC_ARG_TYPE_OBJECT: + var = ObjectToPPVar(arg->arrays.oval); + break; + case NACL_SRPC_ARG_TYPE_VARIANT_ARRAY: + case NACL_SRPC_ARG_TYPE_INVALID: + default: + *exception = "variant array and invalid argument types are not supproted"; + } + PLUGIN_PRINTF((" NaClSrpcArgToPPVar (return var=%s, exception=%s)\n", + var.DebugString().c_str(), exception->DebugString().c_str())); + return var; +} + +} // namespace plugin diff --git a/ppapi/native_client/src/trusted/plugin/var_utils.h b/ppapi/native_client/src/trusted/plugin/var_utils.h new file mode 100644 index 0000000..676fb6a --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/var_utils.h @@ -0,0 +1,38 @@ +/* + * Copyright 2010 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. + */ + +// Utility functions for handling PPAPI Var's. + + +#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_VAR_UTILS_H_ +#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_VAR_UTILS_H_ + +#include <string> + +#include "native_client/src/include/nacl_string.h" +#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "native_client/src/trusted/plugin/plugin.h" +#include "ppapi/cpp/var.h" + +namespace plugin { + +nacl::string NameAsString(const pp::Var& name); + +bool PPVarToAllocateNaClSrpcArg(const pp::Var& var, + NaClSrpcArg* arg, + pp::Var* exception); + +bool PPVarToNaClSrpcArg(const pp::Var& var, + NaClSrpcArg* arg, + pp::Var* exception); + +pp::Var NaClSrpcArgToPPVar(const NaClSrpcArg* arg, + Plugin* plugin, + pp::Var* exception); + +} // namespace plugin + +#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_VAR_UTILS_H_ diff --git a/ppapi/native_client/src/trusted/plugin/win/nacl_plugin.rc b/ppapi/native_client/src/trusted/plugin/win/nacl_plugin.rc new file mode 100644 index 0000000..4dd3354 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/win/nacl_plugin.rc @@ -0,0 +1,102 @@ +// Microsoft Visual C++ generated resource script. +// +// #include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "windows.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "FileDescription", "NativeClient Execution Environment" + VALUE "FileVersion", "1, 0, 0, 1" + VALUE "InternalName", "nacl_plugin" + VALUE "LegalCopyright", "Copyright (C) 2007, 2008" + VALUE "MIMEType", "application/x-nacl" + VALUE "OriginalFilename", "nacl_plugin.dll" + VALUE "ProductName", "NativeClient Execution Environment" + VALUE "ProductVersion", "1, 0, 0, 1" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/ppapi/native_client/tests/ppapi/nacl.scons b/ppapi/native_client/tests/ppapi/nacl.scons new file mode 100644 index 0000000..99adc8d --- /dev/null +++ b/ppapi/native_client/tests/ppapi/nacl.scons @@ -0,0 +1,62 @@ +# -*- python -*- +# Copyright 2010 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. + +import gyp_extract + +Import('env') + +env.Prepend(CPPDEFINES=['XP_UNIX']) + +# TODO(robertm): those should not be necessary once we go -std=c99 +env.FilterOut(CFLAGS=['-pedantic']) +env.FilterOut(CCFLAGS=['-pedantic']) + + +# Load ppapi_cpp.gypi +ppapi_cpp_gypi = gyp_extract.LoadGypFile( + env.File('$SOURCE_ROOT/ppapi/ppapi_cpp.gypi').abspath) + +# From ppapi_cpp.gypi:ppapi_cpp_objects:cpp/[^/]*\.h +cpp_headers = gyp_extract.GypTargetSources( + ppapi_cpp_gypi, 'ppapi_cpp_objects', 'cpp/[^/]*\.h') +cpp_headers = ['ppapi/' + + header_file for header_file in cpp_headers] + +# From ppapi_cpp.gypi:ppapi_cpp_objects:cpp/dev/[^/]*\.h +cpp_dev_headers = gyp_extract.GypTargetSources( + ppapi_cpp_gypi, 'ppapi_cpp_objects', 'cpp/dev/[^/]*\.h') +cpp_dev_headers = ['ppapi/' + + header_file for header_file in cpp_dev_headers] + + +def EmitHeaderTest(target=None, source=None, env=None): + fh = open(target[0].path, 'w') + for header in env['TEST_HEADERS']: + fh.write('#include "%s"\n' % header) + fh.close() + return 0 + + +env.Append(CPPPATH=['$SOURCE_ROOT/ppapi/lib/gl/include']) +cpp_header_test_cc = env.Command( + '$OBJ_ROOT/gen/native_client/test/ppapi/cpp_header_test.cc', + [], Action(EmitHeaderTest, varlist=['TEST_HEADERS']), + TEST_HEADERS=cpp_headers) + +cpp_dev_header_test_cc = env.Command( + '$OBJ_ROOT/gen/native_client/test/ppapi/cpp_dev_header_test.cc', + [], Action(EmitHeaderTest, varlist=['TEST_HEADERS']), + TEST_HEADERS=cpp_dev_headers) + + +ppapi_header_test_inputs = [ + cpp_header_test_cc, + cpp_dev_header_test_cc, + 'opengl_header_test.c', + 'opengl_cpp_header_test.cc', +] + +# Build-only test to make sure the header layout for ppapi is correct. +env.ComponentLibrary('header_test', ppapi_header_test_inputs) diff --git a/ppapi/native_client/tests/ppapi/opengl_cpp_header_test.cc b/ppapi/native_client/tests/ppapi/opengl_cpp_header_test.cc new file mode 100644 index 0000000..4c12256 --- /dev/null +++ b/ppapi/native_client/tests/ppapi/opengl_cpp_header_test.cc @@ -0,0 +1,10 @@ +// Copyright (c) 2010 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. + +// This is a build test that includes the basic OpenGL ES 2 headers, to make +// sure that the header layout in the NaCl toolchain is correct. Note that +// unlike the cpp header test files, this is not generated by a script. + +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> diff --git a/ppapi/native_client/tests/ppapi/opengl_header_test.c b/ppapi/native_client/tests/ppapi/opengl_header_test.c new file mode 100644 index 0000000..3eab3c9 --- /dev/null +++ b/ppapi/native_client/tests/ppapi/opengl_header_test.c @@ -0,0 +1,12 @@ +/* Copyright (c) 2010 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. + */ + +/* This is a build test that includes the basic OpenGL ES 2 headers, to make + * sure that the header layout in the NaCl toolchain is correct. Note that + * unlike the cpp header test files, this is not generated by a script. + */ + +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> diff --git a/ppapi/native_client/tests/ppapi_browser/bad/nacl.scons b/ppapi/native_client/tests/ppapi_browser/bad/nacl.scons new file mode 100644 index 0000000..1ee6714 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/bad/nacl.scons @@ -0,0 +1,98 @@ +# -*- python -*- +# 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. +# +# Tests fatal errors that occur during loading. +# (See ppapi_browser/crash for fatal errors that occur after loading). +# TODO(polina): rename the directory and browser test to bad_load +# +# Manual testing with localhost:5103/scons-out/.../staging/ppapi_bad.html: +# scons --mode=nacl ppapi_bad +# Automatic testing: +# scons run_ppapi_bad_browser_test +# + +Import('env') + +# TODO(robertm): those should not be necessary once we go -std=c99 +env.FilterOut(CFLAGS=['-pedantic']) +env.FilterOut(CCFLAGS=['-pedantic']) + +ppapi_bad_files = [ + 'ppapi_bad.html', + 'ppapi_bad.js', + 'ppapi_bad_crossorigin.nmf', + 'ppapi_bad_doesnotexist.nmf', + 'ppapi_bad_doesnotexist_nexe_only.nmf', + 'ppapi_bad_magic.nmf', + 'ppapi_bad_manifest_uses_nexes.nmf', + 'ppapi_bad_manifest_bad_files.nmf', + env.File('${SCONSTRUCT_DIR}/tools/browser_tester/browserdata/nacltest.js') + ] +ppapi_bad = env.Replicate('${STAGING_DIR}', ppapi_bad_files) + + +# Compile all nexes embedded into the above html +for kind in [ 'ppp_initialize', 'ppp_initialize_crash', + 'no_ppp_instance', 'get_ppp_instance_crash', + 'get_ppp_messaging_crash', 'get_ppp_printing_crash', + 'ppp_instance_didcreate', 'ppp_instance_didcreate_crash', + 'event_replay_crash' + ]: + bad_nmf = 'ppapi_bad_%s.nmf' % kind + bad_nexe = ('ppapi_bad_%s_%s' % (kind, env.get('TARGET_FULLARCH'))) + env.ComponentProgram(bad_nexe, + ['ppapi_bad_%s.cc' % kind], + EXTRA_LIBS=['${PPAPI_LIBS}', + 'platform', + 'pthread', + 'gio']) + + env.Publish(bad_nexe, 'run', [bad_nmf]) + ppapi_bad_files.extend(env.ExtractPublishedFiles(bad_nexe)) + env.Depends(ppapi_bad, env.Alias(bad_nexe)) + +# "scons --mode=nacl ppapi_bad" will publish the html and all of its +# dependencies to scons-out. +env.Alias('ppapi_bad', ppapi_bad) + +node = env.PPAPIBrowserTester( + 'ppapi_bad_browser_test.out', + url='ppapi_bad.html', + files=[env.File(f) for f in ppapi_bad_files], + args=['--allow_404']) + +env.AddNodeToTestSuite(node, + ['chrome_browser_tests'], + 'run_ppapi_bad_browser_test', + is_broken=env.PPAPIBrowserTesterIsBroken()) + + +# Bad nexe tests that won't work in PNaCl (native) +# For example, partly_invalid.nexe has inline assembly in its source files. + +ppapi_bad_native_files = [ + env.File('ppapi_bad_native.html'), + env.File('partly_invalid.nmf'), + env.File('${SCONSTRUCT_DIR}/tests/ppapi_browser/progress_events/' + + 'ppapi_progress_events.js'), + env.File('${SCONSTRUCT_DIR}/tools/browser_tester/browserdata/nacltest.js') + ] +replicated_files = env.Replicate('${STAGING_DIR}', ppapi_bad_native_files) +env.Alias('all_programs', replicated_files) + +partly_invalid = env.File('${STAGING_DIR}/partly_invalid${PROGSUFFIX}') +ppapi_bad_native_files.append(partly_invalid) + +node = env.PPAPIBrowserTester( + 'ppapi_bad_native_test.out', + url='ppapi_bad_native.html', + files=ppapi_bad_native_files, + ) + +env.AddNodeToTestSuite(node, + ['chrome_browser_tests'], + 'run_ppapi_bad_native_test', + is_broken=env.PPAPIBrowserTesterIsBroken() or + env.Bit('bitcode')) diff --git a/ppapi/native_client/tests/ppapi_browser/bad/partly_invalid.nmf b/ppapi/native_client/tests/ppapi_browser/bad/partly_invalid.nmf new file mode 100644 index 0000000..c5e122f --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/bad/partly_invalid.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "partly_invalid.nexe"}, + "x86-64": {"url": "partly_invalid.nexe"}, + "arm": {"url": "partly_invalid.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad.html b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad.html new file mode 100644 index 0000000..964af01 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad.html @@ -0,0 +1,207 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + <!-- + 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. + --> + <head> + <META HTTP-EQUIV="Pragma" CONTENT="no-cache" /> + <META HTTP-EQUIV="Expires" CONTENT="-1" /> + <script type="text/javascript" src="nacltest.js"> </script> + <script type="text/javascript" src="ppapi_bad.js"> </script> + <title> PPAPI bad manifest/nexe URLs </title> + <style type="text/css"> + .naclModule { background-color: gray; margin: 2px 2px; } + </style> + </head> +<body id="body"> +<script type="text/javascript"> +//<![CDATA[ + +function declareTests(tester) { + // 'bad_magic' loads a manifest, then loads a nexe that tests as invalid. + badLoadTest( + tester, + 'bad_magic', + 'ppapi_bad_magic.nmf', + 'NaCl module load failed: Too many program header entries in ELF file'); + + // 'cross_origin' loads a manifest, then tries to load a cross-origin nexe. + badLoadTest( + tester, + 'cross_origin', + 'ppapi_bad_crossorigin.nmf', + 'NaCl module load failed: could not load nexe url.'); + + // 'cross_manifest' tries to load a cross-origin manifest. + badLoadTest( + tester, + 'cross_manifest', + 'http://www.google.com/crossorigin.manifest', + 'NaCl module load failed: could not load manifest url.'); + + // 'nonexistent_nexe' loads a manifest, then tries to load a nonexistent nexe, + // given both a nexe and a portable program to choose from. + badLoadTest( + tester, + 'nonexistent_nexe', + 'ppapi_bad_doesnotexist.nmf', + 'NaCl module load failed: could not load nexe url.'); + + // 'nonexistent_nexe_only' loads a manifest, then tries to load a nonexistent + // nexe, given only a nexe to choose from. + badLoadTest( + tester, + 'nonexistent_nexe_only', + 'ppapi_bad_doesnotexist_nexe_only.nmf', + 'NaCl module load failed: could not load nexe url.'); + + // 'nonexistent_manifest' tries to load a nonexistent manifest. + badLoadTest( + tester, + 'nonexistent_manifest', + 'doesnotexist.manifest', + 'NaCl module load failed: could not load manifest url.'); + + // 'bad_manifest' loads an invalid manifest. + badLoadTest( + tester, + 'bad_manifest', + 'ppapi_bad.html', + 'NaCl module load failed: manifest JSON parsing failed: * Line 1, Column 1\n Syntax error: value, object or array expected.\n'); + + // 'bad_manifest_uses_nexes' loads a manifest with an obsolete 'nexes' section. + badLoadTest( + tester, + 'bad_manifest_uses_nexes', + 'ppapi_bad_manifest_uses_nexes.nmf', + 'NaCl module load failed: manifest: missing \'program\' section.'); + + // 'bad_manifest_bad_files' loads a manifest with a bad 'files' section. + badLoadTest( + tester, + 'bad_manifest_bad_files', + 'ppapi_bad_manifest_bad_files.nmf', + 'NaCl module load failed: manifest: file \'file.txt\' no version given for current arch and no portable version found.'); + + ////////////////////////////////////// + // Initialization errors begin here // + ////////////////////////////////////// + + // 'bad_ppp_initialize' loads a manifest, then loads a nexe that fails to + // initialize PPAPI module + badLoadTest( + tester, + 'bad_ppp_initialize', + 'ppapi_bad_ppp_initialize.nmf', + 'NaCl module load failed: could not initialize module.'); + + // 'bad_ppp_initialize_crash' loads a manifest, then loads a nexe that crashes + // before initializing PPAPI module + badLoadTest( + tester, + 'bad_ppp_initialize_crash', + 'ppapi_bad_ppp_initialize_crash.nmf', + 'NaCl module load failed: could not initialize module.'); + + // 'bad_no_ppp_instance' loads a manifest, then loads a nexe that fails to + // get the required PPP_Instance interface + badLoadTest( + tester, + 'bad_no_ppp_instance', + 'ppapi_bad_no_ppp_instance.nmf', + 'NaCl module load failed: could not initialize module.'); + + // 'bad_get_ppp_instance_crash' loads a manifest, then loads a nexe that + // crashes when getting the required PPP_Instance interface + badLoadTest( + tester, + 'bad_get_ppp_instance_crash', + 'ppapi_bad_get_ppp_instance_crash.nmf', + 'NaCl module load failed: could not initialize module.'); + + // 'bad_get_ppp_messaging_crash' loads a manifest, then loads a nexe that + // crashes when getting the optional PPP_Messaging interface, which is done + // on init. + badLoadTest( + tester, + 'bad_get_ppp_messaging_crash', + 'ppapi_bad_get_ppp_messaging_crash.nmf', + 'NaCl module load failed: could not initialize module.'); + + // 'bad_get_ppp_printing_crash' loads a manifest, then loads a nexe that + // crashes when getting the optional PPP_Printing interface, which is done + // right after creation, but before loadEnd is dispatched. + badLoadTest( + tester, + 'bad_get_ppp_printing_crash', + 'ppapi_bad_get_ppp_printing_crash.nmf', + 'NaCl module load failed: instance crashed after creation.'); + + // 'bad_ppp_instance_didcreate' loads a manifest, then loads a nexe that fails + // to create the instance + badLoadTest( + tester, + 'bad_ppp_instance_didcreate', + 'ppapi_bad_ppp_instance_didcreate.nmf', + 'NaCl module load failed: could not create instance.'); + + // 'bad_ppp_instance_didcreate_crash' loads a manifest, then loads a nexe that + // crashes before creating the instance. + badLoadTest( + tester, + 'bad_ppp_instance_didcreate_crash', + 'ppapi_bad_ppp_instance_didcreate_crash.nmf', + 'NaCl module load failed: could not create instance.'); + + // 'bad_event_replay_crash' loads a manifest, then loads a nexe and replays + // the events that occured during loading causing the nexe to crash before + // proxy start-up was completed. + badLoadTest( + tester, + 'bad_event_replay_crash', + 'ppapi_bad_event_replay_crash.nmf', + 'NaCl module load failed: instance crashed after creation.'); +} + + +// The driver invoked when the body has finished loading. +function runTests() { + var tester = new Tester($('body')); + tester.loadErrorsAreOK(); + declareTests(tester); + tester.run(); +} +//]]> +</script> + +<!-- The tests will create and remove embeds from this div. --> +<div id="embeds"></div> + +<!-- These two embeds are not automatically tested - visual inspection only. --> + +<embed id="cross_manifest_pdf" + width=100 height=20 + src="http://www.google.com/crossorigin.manifest" + style="background-color:gray" + type="application/pdf" /> + +<!-- This load would have succeeded if the NEXE was from a chrome-extension + URL and NaCl had been registered as handling the PDF MIME type using + the nacl_modules attribute in a Chrome extension manifest. --> + +<embed id="cross_origin_pdf" + width=100 height=20 + src="ppapi_bad_crossorigin.nmf" + style="background-color:gray" + type="application/pdf" /> + +<script type="text/javascript"> +//<![CDATA[ +runTests(); +//]]> +</script> +</body> +</html> diff --git a/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad.js b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad.js new file mode 100644 index 0000000..9501c94 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad.js @@ -0,0 +1,43 @@ +// Helper routines for generating bad load tests. +// Webpage must have an 'embeds' div for injecting NaCl modules. +// Depends on nacltest.js. + +function createModule(id, src) { + return createNaClEmbed({ + id: id, + src: src, + width: 100, + height: 20 + }); +} + + +function addModule(module) { + $('embeds').appendChild(module); +} + + +function removeModule(module) { + $('embeds').removeChild(module); +} + + +function badLoadTest(tester, id, src, error_string) { + tester.addAsyncTest(id, function(test){ + var module = createModule(id, src); + + test.expectEvent(module, 'load', function(e) { + removeModule(module); + test.fail('Module loaded successfully.'); + }); + test.expectEvent(module, 'error', function(e) { + test.assertEqual(module.readyState, 4); + test.assertEqual(module.lastError, error_string); + test.expectEvent(module, 'loadend', function(e) { + removeModule(module); + test.pass(); + }); + }); + addModule(module); + }); +} diff --git a/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_crossorigin.nmf b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_crossorigin.nmf new file mode 100644 index 0000000..22dba61 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_crossorigin.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "http://www.google.com/crossorigin.nexe"}, + "x86-64": {"url": "http://www.google.com/crossorigin.nexe"}, + "arm": {"url": "http://www.google.com/crossorigin.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_doesnotexist.nmf b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_doesnotexist.nmf new file mode 100644 index 0000000..fef6a67 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_doesnotexist.nmf @@ -0,0 +1,8 @@ +{ + "program": { + "x86-32": {"url": "doesnotexist.nexe"}, + "x86-64": {"url": "doesnotexist.nexe"}, + "arm": {"url": "doesnotexist.nexe"}, + "portable": {"url": "doesnotexist.pexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_doesnotexist_nexe_only.nmf b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_doesnotexist_nexe_only.nmf new file mode 100644 index 0000000..8578bcb --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_doesnotexist_nexe_only.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "doesnotexist.nexe"}, + "x86-64": {"url": "doesnotexist.nexe"}, + "arm": {"url": "doesnotexist.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_event_replay_crash.cc b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_event_replay_crash.cc new file mode 100644 index 0000000..251fc8c --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_event_replay_crash.cc @@ -0,0 +1,65 @@ +// 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 <cstdio> +#include <cstdlib> +#include <cstring> + +#include "native_client/src/shared/platform/nacl_check.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_var.h" + +#include "ppapi/c/ppb.h" +#include "ppapi/c/ppb_instance.h" +#include "ppapi/c/ppp_instance.h" +#include "ppapi/c/ppp.h" + +PP_EXPORT int32_t PPP_InitializeModule(PP_Module module_id, + PPB_GetInterface get_browser_interface) { + printf("PPP_InitializeModule\n"); + return PP_OK; +} + +PP_EXPORT void PPP_ShutdownModule() { + printf("PPP_ShutdownModule\n"); + fflush(stdout); +} + +namespace { + +PP_Bool DidCreate(PP_Instance /*instance*/, + uint32_t /*argc*/, + const char* /*argn*/[], + const char* /*argv*/[]) { + return PP_TRUE; +} + +void DidDestroy(PP_Instance /*instance*/) { +} + +void DidChangeFocus(PP_Instance /*instance*/, PP_Bool /*has_focus*/) { +} + +PP_Bool HandleDocumentLoad(PP_Instance /*instance*/, PP_Resource /*loader*/) { + return PP_FALSE; +} + +const struct PPP_Instance instance_interface = { + DidCreate, + DidDestroy, + NULL, // Calling DidChangeView will cause a crash! + DidChangeFocus, + HandleDocumentLoad +}; + +} // namespace + +PP_EXPORT const void* PPP_GetInterface(const char* interface_name) { + printf("PPP_GetInterface(%s)\n", interface_name); + if (0 == std::strcmp(interface_name, PPP_INSTANCE_INTERFACE)) // Required. + return reinterpret_cast<const void*>(&instance_interface); + return NULL; +} diff --git a/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_event_replay_crash.nmf b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_event_replay_crash.nmf new file mode 100644 index 0000000..4f928cd --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_event_replay_crash.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_bad_event_replay_crash_x86-32.nexe"}, + "x86-64": {"url": "ppapi_bad_event_replay_crash_x86-64.nexe"}, + "arm": {"url": "ppapi_bad_event_replay_crash_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_get_ppp_instance_crash.cc b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_get_ppp_instance_crash.cc new file mode 100644 index 0000000..4068d57 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_get_ppp_instance_crash.cc @@ -0,0 +1,35 @@ +// 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 <cstdio> +#include <cstdlib> +#include <cstring> + +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/ppb.h" +#include "ppapi/c/ppp_instance.h" +#include "ppapi/c/dev/ppb_layer_compositor_dev.h" + +#include "ppapi/c/ppp.h" + +int32_t PPP_InitializeModule(PP_Module module_id, + PPB_GetInterface get_browser_interface) { + printf("PPP_InitializeModule\n"); + return PP_OK; +} + +PP_EXPORT void PPP_ShutdownModule() { + printf("PPP_ShutdownModule\n"); + fflush(stdout); +} + +PP_EXPORT const void* PPP_GetInterface(const char* interface_name) { + printf("PPP_GetInterface(%s)\n", interface_name); + if (0 == std::strcmp(interface_name, PPP_INSTANCE_INTERFACE)) // Required. + CRASH; + return NULL; +} diff --git a/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_get_ppp_instance_crash.nmf b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_get_ppp_instance_crash.nmf new file mode 100644 index 0000000..7d3a323 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_get_ppp_instance_crash.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_bad_get_ppp_instance_crash_x86-32.nexe"}, + "x86-64": {"url": "ppapi_bad_get_ppp_instance_crash_x86-64.nexe"}, + "arm": {"url": "ppapi_bad_get_ppp_instance_crash_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_get_ppp_messaging_crash.cc b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_get_ppp_messaging_crash.cc new file mode 100644 index 0000000..273c485 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_get_ppp_messaging_crash.cc @@ -0,0 +1,73 @@ +// 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 <cstdio> +#include <cstdlib> +#include <cstring> + +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_var.h" + +#include "ppapi/c/ppb.h" +#include "ppapi/c/ppp_instance.h" +#include "ppapi/c/ppp_messaging.h" +#include "ppapi/c/ppp.h" + +PP_EXPORT int32_t PPP_InitializeModule(PP_Module module_id, + PPB_GetInterface get_browser_interface) { + printf("PPP_InitializeModule\n"); + return PP_OK; +} + +PP_EXPORT void PPP_ShutdownModule() { + printf("PPP_ShutdownModule\n"); + fflush(stdout); +} + +namespace { + +PP_Bool DidCreate(PP_Instance /*instance*/, + uint32_t /*argc*/, + const char* /*argn*/[], + const char* /*argv*/[]) { + return PP_TRUE; +} + +void DidDestroy(PP_Instance /*instance*/) { +} + +void DidChangeView(PP_Instance /*instance*/, + const struct PP_Rect* /*position*/, + const struct PP_Rect* /*clip*/) { +} + +void DidChangeFocus(PP_Instance /*instance*/, PP_Bool /*has_focus*/) { +} + +PP_Bool HandleDocumentLoad(PP_Instance /*instance*/, PP_Resource /*loader*/) { + return PP_FALSE; +} + +const struct PPP_Instance instance_interface = { + DidCreate, + DidDestroy, + DidChangeView, + DidChangeFocus, + HandleDocumentLoad +}; + +} // namespace + +PP_EXPORT const void* PPP_GetInterface(const char* interface_name) { + printf("PPP_GetInterface(%s)\n", interface_name); + if (0 == std::strcmp(interface_name, PPP_INSTANCE_INTERFACE)) // Required. + return reinterpret_cast<const void*>(&instance_interface); + if (0 == std::strcmp(interface_name, PPP_MESSAGING_INTERFACE)) + CRASH; + return NULL; +} diff --git a/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_get_ppp_messaging_crash.nmf b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_get_ppp_messaging_crash.nmf new file mode 100644 index 0000000..e95eea4 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_get_ppp_messaging_crash.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_bad_get_ppp_messaging_crash_x86-32.nexe"}, + "x86-64": {"url": "ppapi_bad_get_ppp_messaging_crash_x86-64.nexe"}, + "arm": {"url": "ppapi_bad_get_ppp_messaging_crash_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_get_ppp_printing_crash.cc b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_get_ppp_printing_crash.cc new file mode 100644 index 0000000..adf2ac1 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_get_ppp_printing_crash.cc @@ -0,0 +1,73 @@ +// 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 <cstdio> +#include <cstdlib> +#include <cstring> + +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_var.h" + +#include "ppapi/c/ppb.h" +#include "ppapi/c/ppp_instance.h" +#include "ppapi/c/dev/ppp_printing_dev.h" +#include "ppapi/c/ppp.h" + +PP_EXPORT int32_t PPP_InitializeModule(PP_Module module_id, + PPB_GetInterface get_browser_interface) { + printf("PPP_InitializeModule\n"); + return PP_OK; +} + +PP_EXPORT void PPP_ShutdownModule() { + printf("PPP_ShutdownModule\n"); + fflush(stdout); +} + +namespace { + +PP_Bool DidCreate(PP_Instance /*instance*/, + uint32_t /*argc*/, + const char* /*argn*/[], + const char* /*argv*/[]) { + return PP_TRUE; +} + +void DidDestroy(PP_Instance /*instance*/) { +} + +void DidChangeView(PP_Instance /*instance*/, + const struct PP_Rect* /*position*/, + const struct PP_Rect* /*clip*/) { +} + +void DidChangeFocus(PP_Instance /*instance*/, PP_Bool /*has_focus*/) { +} + +PP_Bool HandleDocumentLoad(PP_Instance /*instance*/, PP_Resource /*loader*/) { + return PP_FALSE; +} + +const struct PPP_Instance instance_interface = { + DidCreate, + DidDestroy, + DidChangeView, + DidChangeFocus, + HandleDocumentLoad +}; + +} // namespace + +PP_EXPORT const void* PPP_GetInterface(const char* interface_name) { + printf("PPP_GetInterface(%s)\n", interface_name); + if (0 == std::strcmp(interface_name, PPP_INSTANCE_INTERFACE)) // Required. + return reinterpret_cast<const void*>(&instance_interface); + if (0 == std::strcmp(interface_name, PPP_PRINTING_DEV_INTERFACE)) + CRASH; + return NULL; +} diff --git a/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_get_ppp_printing_crash.nmf b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_get_ppp_printing_crash.nmf new file mode 100644 index 0000000..cbbe68e --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_get_ppp_printing_crash.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_bad_get_ppp_printing_crash_x86-32.nexe"}, + "x86-64": {"url": "ppapi_bad_get_ppp_printing_crash_x86-64.nexe"}, + "arm": {"url": "ppapi_bad_get_ppp_printing_crash_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_magic.nmf b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_magic.nmf new file mode 100644 index 0000000..756c42e --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_magic.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_bad.html"}, + "x86-64": {"url": "ppapi_bad.html"}, + "arm": {"url": "ppapi_bad.html"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_manifest_bad_files.nmf b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_manifest_bad_files.nmf new file mode 100644 index 0000000..30bc7ad --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_manifest_bad_files.nmf @@ -0,0 +1,12 @@ +{ + "program": { + "x86-32": {"url": "ppapi_bad_no_ppp_instance_x86-32.nexe"}, + "x86-64": {"url": "ppapi_bad_no_ppp_instance_x86-64.nexe"}, + "arm": {"url": "ppapi_bad_no_ppp_instance_arm.nexe"} + }, + "files": { + "file.txt": { + "unknown_arch": {"url": "file.txt"} + } + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_manifest_uses_nexes.nmf b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_manifest_uses_nexes.nmf new file mode 100644 index 0000000..286ed7b --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_manifest_uses_nexes.nmf @@ -0,0 +1,7 @@ +{ + "nexes": { + "x86-32": "doesnotexist.nexe", + "x86-64": "doesnotexist.nexe", + "arm": "doesnotexist.nexe" + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_native.html b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_native.html new file mode 100644 index 0000000..fa43c04 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_native.html @@ -0,0 +1,50 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + <!-- Copyright 2011 Google Inc. All rights reserved. --> + <head> + <META HTTP-EQUIV="Pragma" CONTENT="no-cache" /> + <META HTTP-EQUIV="Expires" CONTENT="-1" /> + <script type="text/javascript" src="nacltest.js"> </script> + <script type="text/javascript" src="ppapi_progress_events.js"> </script> + <title> PPAPI bad manifest/nexe URLs </title> + </head> + <body id="body"> +<script type="text/javascript"> +//<![CDATA[ +var tester = new Tester($('body')); + +// This nexe should fail validation inside the sel_ldr. +testProgressEventStateMachine( + tester, + 'partly_invalid', + 1, // progressMinCount + 1, // errorCount + 0, // abortCount + 0, // loadCount + 'NaCl module load failed: Validation failure. File violates Native Client safety rules.'); + +// The driver invoked when the body has finished loading. +function runTests() { + tester.loadErrorsAreOK(); + tester.waitFor($('partly_invalid')); + tester.run(); +} +// Set all the listeners on the body. +setListeners($('body')); +//]]> +</script> + <embed id="partly_invalid" + class="naclModule" + width=100 height=20 + src="partly_invalid.nmf" + style="background-color:gray" + type="application/x-nacl" /> + + <script type="text/javascript"> + //<![CDATA[ + runTests(); + //]]> + </script> + </body> +</html> diff --git a/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_no_ppp_instance.cc b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_no_ppp_instance.cc new file mode 100644 index 0000000..0832b76 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_no_ppp_instance.cc @@ -0,0 +1,40 @@ +// 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 <cstdio> +#include <cstdlib> +#include <cstring> + +#include "native_client/src/shared/platform/nacl_check.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/ppb.h" +#include "ppapi/c/ppp_instance.h" +#include "ppapi/c/dev/ppb_layer_compositor_dev.h" + +#include "ppapi/c/ppp.h" + +int32_t PPP_InitializeModule(PP_Module module_id, + PPB_GetInterface get_browser_interface) { + printf("PPP_InitializeModule\n"); + + // Request an unsupported interface. + CHECK(NULL == get_browser_interface(PPB_LAYER_COMPOSITOR_DEV_INTERFACE)); + // Request a supported interface with a bad revision number. + CHECK(NULL == get_browser_interface("PPB_Instance;0.0")); + + return PP_OK; +} + +PP_EXPORT void PPP_ShutdownModule() { + printf("PPP_ShutdownModule\n"); + fflush(stdout); +} + +PP_EXPORT const void* PPP_GetInterface(const char* interface_name) { + printf("PPP_GetInterface(%s)\n", interface_name); + if (0 == std::strcmp(interface_name, PPP_INSTANCE_INTERFACE)) // Required. + return NULL; + return NULL; +} diff --git a/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_no_ppp_instance.nmf b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_no_ppp_instance.nmf new file mode 100644 index 0000000..df93186 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_no_ppp_instance.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_bad_no_ppp_instance_x86-32.nexe"}, + "x86-64": {"url": "ppapi_bad_no_ppp_instance_x86-64.nexe"}, + "arm": {"url": "ppapi_bad_no_ppp_instance_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_ppp_initialize.cc b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_ppp_initialize.cc new file mode 100644 index 0000000..4bf4354 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_ppp_initialize.cc @@ -0,0 +1,30 @@ +// 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 <cstdio> +#include <cstdlib> +#include <cstring> + +#include "native_client/src/include/nacl_macros.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/ppb.h" +#include "ppapi/c/ppp.h" + +PP_EXPORT int32_t PPP_InitializeModule(PP_Module module_id, + PPB_GetInterface get_browser_interface) { + printf("PPP_InitializeModule\n"); + return PP_ERROR_FAILED; +} + +PP_EXPORT void PPP_ShutdownModule() { + printf("PPP_ShutdownModule\n"); + NACL_NOTREACHED(); // If initialization fails, this should not be called. +} + +PP_EXPORT const void* PPP_GetInterface(const char* interface_name) { + printf("PPP_GetInterface\n"); + NACL_NOTREACHED(); // If initialization fails, this should not be called. + return NULL; +} diff --git a/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_ppp_initialize.nmf b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_ppp_initialize.nmf new file mode 100644 index 0000000..0e62793 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_ppp_initialize.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_bad_ppp_initialize_x86-32.nexe"}, + "x86-64": {"url": "ppapi_bad_ppp_initialize_x86-64.nexe"}, + "arm": {"url": "ppapi_bad_ppp_initialize_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_ppp_initialize_crash.cc b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_ppp_initialize_crash.cc new file mode 100644 index 0000000..7740f9b --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_ppp_initialize_crash.cc @@ -0,0 +1,73 @@ +// 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 <cstdio> +#include <cstdlib> +#include <cstring> + +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/src/include/nacl_macros.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_var.h" +#include "ppapi/c/ppb.h" +#include "ppapi/c/ppp_instance.h" +#include "ppapi/c/ppp.h" + +PP_EXPORT int32_t PPP_InitializeModule(PP_Module module_id, + PPB_GetInterface get_browser_interface) { + printf("PPP_InitializeModule\n"); + CHECK(NULL == get_browser_interface(NULL)); // Crash! + + return PP_OK; +} + +PP_EXPORT void PPP_ShutdownModule() { + printf("PPP_ShutdownModule\n"); +} + +// Ensure that all other loading steps do not generate errors that might mask +// a missing crash above. + +namespace { + +PP_Bool DidCreate(PP_Instance /*instance*/, + uint32_t /*argc*/, + const char* /*argn*/[], + const char* /*argv*/[]) { + return PP_TRUE; +} + +void DidDestroy(PP_Instance /*instance*/) { +} + +void DidChangeView(PP_Instance /*instance*/, + const struct PP_Rect* /*position*/, + const struct PP_Rect* /*clip*/) { +} + +void DidChangeFocus(PP_Instance /*instance*/, PP_Bool /*has_focus*/) { +} + +PP_Bool HandleDocumentLoad(PP_Instance /*instance*/, PP_Resource /*loader*/) { + return PP_FALSE; +} + +const struct PPP_Instance instance_interface = { + DidCreate, + DidDestroy, + DidChangeView, + DidChangeFocus, + HandleDocumentLoad +}; + +} // namespace + +PP_EXPORT const void* PPP_GetInterface(const char* interface_name) { + printf("PPP_GetInterface\n"); + if (0 == std::strcmp(interface_name, PPP_INSTANCE_INTERFACE)) // Required. + return reinterpret_cast<const void*>(&instance_interface); + return NULL; +} diff --git a/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_ppp_initialize_crash.nmf b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_ppp_initialize_crash.nmf new file mode 100644 index 0000000..0dc3301 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_ppp_initialize_crash.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_bad_ppp_initialize_crash_x86-32.nexe"}, + "x86-64": {"url": "ppapi_bad_ppp_initialize_crash_x86-64.nexe"}, + "arm": {"url": "ppapi_bad_ppp_initialize_crash_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_ppp_instance_didcreate.cc b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_ppp_instance_didcreate.cc new file mode 100644 index 0000000..77ff6b7 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_ppp_instance_didcreate.cc @@ -0,0 +1,70 @@ +// 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 <cstdio> +#include <cstdlib> +#include <cstring> + +#include "native_client/src/shared/platform/nacl_check.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_var.h" + +#include "ppapi/c/ppb.h" +#include "ppapi/c/ppb_instance.h" +#include "ppapi/c/ppp_instance.h" +#include "ppapi/c/ppp.h" + +PP_EXPORT int32_t PPP_InitializeModule(PP_Module module_id, + PPB_GetInterface get_browser_interface) { + printf("PPP_InitializeModule\n"); + return PP_OK; +} + +PP_EXPORT void PPP_ShutdownModule() { + printf("PPP_ShutdownModule\n"); + fflush(stdout); +} + +namespace { + +PP_Bool DidCreate(PP_Instance /*instance*/, + uint32_t /*argc*/, + const char* /*argn*/[], + const char* /*argv*/[]) { + return PP_FALSE; +} + +void DidDestroy(PP_Instance /*instance*/) { +} + +void DidChangeView(PP_Instance /*instance*/, + const struct PP_Rect* /*position*/, + const struct PP_Rect* /*clip*/) { +} + +void DidChangeFocus(PP_Instance /*instance*/, PP_Bool /*has_focus*/) { +} + +PP_Bool HandleDocumentLoad(PP_Instance /*instance*/, PP_Resource /*loader*/) { + return PP_FALSE; +} + +const struct PPP_Instance instance_interface = { + DidCreate, + DidDestroy, + DidChangeView, + DidChangeFocus, + HandleDocumentLoad +}; + +} // namespace + +PP_EXPORT const void* PPP_GetInterface(const char* interface_name) { + printf("PPP_GetInterface(%s)\n", interface_name); + if (0 == std::strcmp(interface_name, PPP_INSTANCE_INTERFACE)) // Required. + return reinterpret_cast<const void*>(&instance_interface); + return NULL; +} diff --git a/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_ppp_instance_didcreate.nmf b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_ppp_instance_didcreate.nmf new file mode 100644 index 0000000..0c00062 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_ppp_instance_didcreate.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_bad_ppp_instance_didcreate_x86-32.nexe"}, + "x86-64": {"url": "ppapi_bad_ppp_instance_didcreate_x86-64.nexe"}, + "arm": {"url": "ppapi_bad_ppp_instance_didcreate_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_ppp_instance_didcreate_crash.cc b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_ppp_instance_didcreate_crash.cc new file mode 100644 index 0000000..13d8225 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_ppp_instance_didcreate_crash.cc @@ -0,0 +1,59 @@ +// 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 <cstdio> +#include <cstdlib> +#include <cstring> + +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_var.h" + +#include "ppapi/c/ppb.h" +#include "ppapi/c/ppb_instance.h" +#include "ppapi/c/ppp_instance.h" +#include "ppapi/c/ppp.h" + +PP_EXPORT int32_t PPP_InitializeModule(PP_Module module_id, + PPB_GetInterface get_browser_interface) { + printf("PPP_InitializeModule\n"); + return PP_OK; +} + +PP_EXPORT void PPP_ShutdownModule() { + printf("PPP_ShutdownModule\n"); + fflush(stdout); +} + +namespace { + +PP_Bool DidCreate(PP_Instance /*instance*/, + uint32_t /*argc*/, + const char* /*argn*/[], + const char* /*argv*/[]) { + CRASH; + return PP_FALSE; +} + +const struct PPP_Instance instance_interface = { + DidCreate, + // Normally one is not alowed to register NULLs for functions, but + // since DidCreate is going to crash, these will never be called. + NULL, + NULL, + NULL, + NULL +}; + +} // namespace + +PP_EXPORT const void* PPP_GetInterface(const char* interface_name) { + printf("PPP_GetInterface(%s)\n", interface_name); + if (0 == std::strcmp(interface_name, PPP_INSTANCE_INTERFACE)) // Required. + return reinterpret_cast<const void*>(&instance_interface); + return NULL; +} diff --git a/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_ppp_instance_didcreate_crash.nmf b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_ppp_instance_didcreate_crash.nmf new file mode 100644 index 0000000..0b4346b --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/bad/ppapi_bad_ppp_instance_didcreate_crash.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_bad_ppp_instance_didcreate_crash_x86-32.nexe"}, + "x86-64": {"url": "ppapi_bad_ppp_instance_didcreate_crash_x86-64.nexe"}, + "arm": {"url": "ppapi_bad_ppp_instance_didcreate_arm_crash.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/crash/nacl.scons b/ppapi/native_client/tests/ppapi_browser/crash/nacl.scons new file mode 100644 index 0000000..7da4e0f --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/crash/nacl.scons @@ -0,0 +1,48 @@ +# -*- python -*- +# 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. +# +# Tests fatal errors that occur after loading. +# (See ppapi_browser/bad for fatal errors that occur during loading). +# +# The tests use ppapi_test_lib. + +Import('env') + +env.Prepend(CPPDEFINES=['XP_UNIX']) + +crash_types = ['via_check_failure', 'via_exit_call', 'in_callback'] +published_files = [] + +for crash_type in crash_types: + nexe = 'ppapi_crash_%s_%s' % (crash_type, env.get('TARGET_FULLARCH')) + env.Alias('ppapi_crash_%s${PROGSUFFIX}' % crash_type, + ['$STAGING_DIR/%s${PROGSUFFIX}' % nexe]) + + env.ComponentProgram( + nexe, + ['ppapi_crash_%s.cc' % crash_type], + EXTRA_LIBS=['${PPAPI_LIBS}', + 'ppapi_test_lib', + 'platform', + 'pthread', + 'gio']) + +# TODO(polina): follow ppapi_browser/bad nacl.scons to publish html only once +# and to associate all nexes and nmf files with one target that can be +# referenced in tests/nacl.scons. + env.Publish(nexe, 'run', + ['ppapi_crash.html', + 'ppapi_crash_%s.nmf' % crash_type ]) + + published_files.extend(env.ExtractPublishedFiles(nexe)) + +node = env.PPAPIBrowserTester('ppapi_crash_browser_test.out', + url='ppapi_crash.html', + files=published_files) + +env.AddNodeToTestSuite(node, + ['chrome_browser_tests'], + 'run_ppapi_crash_browser_test', + is_broken=env.PPAPIBrowserTesterIsBroken()) diff --git a/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash.html b/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash.html new file mode 100644 index 0000000..77b8dfe --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash.html @@ -0,0 +1,55 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + <!-- Copyright (c) 2011 Google Inc. All rights reserved. --> + <head> + <meta http-equiv="Pragma" content="no-cache" /> + <meta http-equiv="Expires" content="-1" /> + <script type="text/javascript" src="nacltest.js"></script> + <title>Nexe Crash Test</title> + </head> + <body> + <h1>Nexe Crash Test</h1> + + <embed type="application/x-nacl" id="crash_via_check_failure" + name="nacl_module" + src="ppapi_crash_via_check_failure.nmf" + width="0" height="0" /> + <embed type="application/x-nacl" id="crash_via_exit_call" + name="nacl_module" + src="ppapi_crash_via_exit_call.nmf" + width="0" height="0" /> + <embed type="application/x-nacl" id="crash_in_callback" + name="nacl_module" + src="ppapi_crash_in_callback.nmf" + width="0" height="0" /> + + <script type="text/javascript"> + //<![CDATA[ + var tester = new Tester(); + function AddTest(plugin, testName, expectedHandler, unexpectedHandler) { + tester.addAsyncTest(testName, function(test) { + plugin.addEventListener( + expectedHandler, + test.wrap(function(e) { test.pass(); }), + false); + plugin.addEventListener( + unexpectedHandler, + test.wrap(function(e) { test.fail(); }), + false); + plugin.postMessage(testName); + }); + tester.waitFor(plugin); + } + + AddTest($('crash_via_check_failure'), + 'CrashViaCheckFailure', 'crash', 'error'); + AddTest($('crash_via_exit_call'), + 'CrashViaExitCall', 'crash', 'error'); + AddTest($('crash_in_callback'), 'CrashInCallback', 'crash', 'error'); + + tester.run(); + //]]> + </script> + </body> +</html> diff --git a/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_in_callback.cc b/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_in_callback.cc new file mode 100644 index 0000000..d121b19 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_in_callback.cc @@ -0,0 +1,34 @@ +// 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/platform/nacl_check.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/ppb_core.h" +#include "native_client/tests/ppapi_test_lib/get_browser_interface.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" + + +namespace { + +void CrashingCallback(void* /*user_data*/, int32_t /*result*/) { + printf("--- CrashingCallback\n"); + CRASH; +} + +void CrashInCallback() { + printf("--- CrashInCallback\n"); + PP_CompletionCallback callback = + PP_MakeCompletionCallback(CrashingCallback, NULL); + PPBCore()->CallOnMainThread(0 /*delay*/, callback, PP_OK); +} + +} // namespace + +void SetupTests() { + RegisterTest("CrashInCallback", CrashInCallback); +} + +void SetupPluginInterfaces() { + // none +} diff --git a/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_in_callback.nmf b/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_in_callback.nmf new file mode 100644 index 0000000..889c75a --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_in_callback.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_crash_in_callback_x86-32.nexe"}, + "x86-64": {"url": "ppapi_crash_in_callback_x86-64.nexe"}, + "arm": {"url": "ppapi_crash_in_callabck.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_via_check_failure.cc b/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_via_check_failure.cc new file mode 100644 index 0000000..179a9af --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_via_check_failure.cc @@ -0,0 +1,24 @@ +// 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/platform/nacl_check.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" + +namespace { + +// This will crash a PPP_Messaging function. +void CrashViaCheckFailure() { + printf("--- CrashViaCheckFailure\n"); + CHECK(false); +} + +} // namespace + +void SetupTests() { + RegisterTest("CrashViaCheckFailure", CrashViaCheckFailure); +} + +void SetupPluginInterfaces() { + // none +} diff --git a/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_via_check_failure.nmf b/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_via_check_failure.nmf new file mode 100644 index 0000000..a7850d1 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_via_check_failure.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_crash_via_check_failure_x86-32.nexe"}, + "x86-64": {"url": "ppapi_crash_via_check_failure_x86-64.nexe"}, + "arm": {"url": "ppapi_crash_via_check_failure_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_via_exit_call.cc b/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_via_exit_call.cc new file mode 100644 index 0000000..03bc2a9 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_via_exit_call.cc @@ -0,0 +1,26 @@ +// 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 <unistd.h> + +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" + +namespace { + +// This will crash a PPP_Messaging function. +void CrashViaExitCall() { + printf("--- CrashViaExitCall\n"); + _exit(0); +} + +} // namespace + +void SetupTests() { + RegisterTest("CrashViaExitCall", CrashViaExitCall); +} + +void SetupPluginInterfaces() { + // none +} diff --git a/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_via_exit_call.nmf b/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_via_exit_call.nmf new file mode 100644 index 0000000..a42a8e0 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_via_exit_call.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_crash_via_exit_call_x86-32.nexe"}, + "x86-64": {"url": "ppapi_crash_via_exit_call_x86-64.nexe"}, + "arm": {"url": "ppapi_crash_via_exit_call_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/extension_mime_handler/manifest.json b/ppapi/native_client/tests/ppapi_browser/extension_mime_handler/manifest.json new file mode 100644 index 0000000..10fad57 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/extension_mime_handler/manifest.json @@ -0,0 +1,13 @@ +{ + "name": "NaCl_MIMETest", + "version": "0.1", + "description": "Tests NaCl MIME type handling capabilities.", + "permissions": [ + "experimental", + "nativeclient" + ], + "nacl_modules": [{ + "path": "ppapi_extension_mime_handler.nmf", + "mime_type": "application/pdf" + }] +} diff --git a/ppapi/native_client/tests/ppapi_browser/extension_mime_handler/mime_test_data.pdf b/ppapi/native_client/tests/ppapi_browser/extension_mime_handler/mime_test_data.pdf new file mode 100644 index 0000000..d77a7ba --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/extension_mime_handler/mime_test_data.pdf @@ -0,0 +1 @@ +This is not an actual pdf file, just a test file so we can verify HandleDocumentLoad. diff --git a/ppapi/native_client/tests/ppapi_browser/extension_mime_handler/nacl.scons b/ppapi/native_client/tests/ppapi_browser/extension_mime_handler/nacl.scons new file mode 100644 index 0000000..537d8bc --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/extension_mime_handler/nacl.scons @@ -0,0 +1,51 @@ +# -*- python -*- +# 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. + +# Test loading a NaCl-enabled Chrome Extension. This also covers parts +# of {ppb,ppp}_instance interfaces that are not testable any other way. + +# The extension registers the nacl module as a content handler for +# application/pdf because it's easy to override that known type, but the +# actual file we use is a plain text file with a .pdf file extension. + +Import('env') + +env.Prepend(CPPDEFINES=['XP_UNIX']) + +nexe = 'ppapi_extension_mime_handler_%s' % env.get('TARGET_FULLARCH') + +env.ComponentProgram( + nexe, + ['ppapi_extension_mime_handler.cc'], + EXTRA_LIBS=['${PPAPI_LIBS}', + 'ppapi_test_lib', + 'pthread', + 'platform', + 'gio']) + +# Copy the extension into place (as a subdir in the staging dir). +dest_copy = env.Replicate('$STAGING_DIR/ppapi_extension_mime_handler', + ['ppapi_extension_mime_handler.nmf', + 'manifest.json', + env.File('$STAGING_DIR/' + nexe + '$PROGSUFFIX')]) + +env.Depends(env.Alias(nexe), dest_copy) + +# Publish the html,js, and pdf. +env.Publish(nexe, 'run', + ['ppapi_extension_mime_handler.html', + 'mime_test_data.pdf']) + +node = env.PPAPIBrowserTester('ppapi_extension_mime_handler.out', + url='ppapi_extension_mime_handler.html', + extensions=[env.Dir('$STAGING_DIR/ppapi_extension_mime_handler')], + files=env.ExtractPublishedFiles(nexe)) + +env.Depends(node, dest_copy) + +env.AddNodeToTestSuite(node, + ['chrome_browser_tests'], + 'run_ppapi_extension_mime_handler_browser_test', + is_broken=env.PPAPIBrowserTesterIsBroken()) diff --git a/ppapi/native_client/tests/ppapi_browser/extension_mime_handler/ppapi_extension_mime_handler.cc b/ppapi/native_client/tests/ppapi_browser/extension_mime_handler/ppapi_extension_mime_handler.cc new file mode 100644 index 0000000..0ae663e --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/extension_mime_handler/ppapi_extension_mime_handler.cc @@ -0,0 +1,169 @@ +// 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 <string.h> + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/tests/ppapi_test_lib/get_browser_interface.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" + +#include "ppapi/c/pp_bool.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_input_event.h" +#include "ppapi/c/ppb_instance.h" +#include "ppapi/c/ppb_url_loader.h" +#include "ppapi/c/ppp_instance.h" + +namespace { + + +// PostMessage is complicated in this test. We're setting up an iframe with +// src=foo where foo is handled by an extension as a content handler. Webkit +// generates the html page with the plugin embed, so we have no way to place +// an event handler on the plugin or body of that page that's guaranteed to +// execute before the plugin initializes. Instead, we're just caching the +// first error (if any) we encounter during load and responding to a normal +// test message to return the results. +const int kDocLoadErrorNone = 0; +const int kDocLoadErrorInit = -1; +int error_in_doc_load_line = kDocLoadErrorInit; + +#define EXPECT_ON_LOAD(condition) \ + do { \ + if (!(condition)) { \ + if (kDocLoadErrorInit == error_in_doc_load_line) { \ + error_in_doc_load_line = __LINE__; \ + } \ + } \ + } while (0); + +#define ON_LOAD_PASSED \ + do { \ + if (kDocLoadErrorInit == error_in_doc_load_line) \ + error_in_doc_load_line = kDocLoadErrorNone; \ + } while (0); + +// Simple 1K buffer to hold the document passed through HandleDocumentLoad. +const uint32_t kMaxFileSize = 1024; +char buffer[kMaxFileSize]; +uint32_t buffer_pos = 0; + +const char kKnownFileContents[] = + "This is not an actual pdf file, just a " + "test file so we can verify HandleDocumentLoad."; + + +PP_Bool DidCreate(PP_Instance instance, + uint32_t argc, + const char* argn[], + const char* argv[]) { + PP_Bool status = DidCreateDefault(instance, argc, argn, argv); + printf("DidCreate! %d\n", static_cast<int>(instance)); + return status; +} + +void DidDestroy(PP_Instance /* instance */) { +} + +void DidChangeView(PP_Instance /* instance */, + const struct PP_Rect* /* position */, + const struct PP_Rect* /* clip */) { +} + +void DidChangeFocus(PP_Instance /* instance */, + PP_Bool /* has_focus */) { +} + +PP_Bool HandleInputEvent(PP_Instance /* instance */, + const struct PP_InputEvent* /* event */) { + return PP_FALSE; +} + +void ReadCallback(void* user_data, int32_t pp_error_or_bytes) { + PP_Resource url_loader = reinterpret_cast<PP_Resource>(user_data); + + EXPECT_ON_LOAD(pp_error_or_bytes >= PP_OK); + // EXPECT_ON_LOAD just records an error, make sure to stop processing too. + // On error we may end up leaking the URLLoader from HandleDocumentLoad. + if (pp_error_or_bytes < PP_OK) + return; + + if (PP_OK == pp_error_or_bytes) { + // Check the contents of the file against the known contents. + int diff = strncmp(buffer, + kKnownFileContents, + strlen(kKnownFileContents)); + EXPECT_ON_LOAD(diff == 0); + PPBURLLoader()->Close(url_loader); + ON_LOAD_PASSED; + } else { + buffer_pos += pp_error_or_bytes; + PP_CompletionCallback callback = + PP_MakeOptionalCompletionCallback(ReadCallback, user_data); + pp_error_or_bytes = + PPBURLLoader()->ReadResponseBody(url_loader, + buffer + buffer_pos, + kMaxFileSize - buffer_pos, + callback); + if (pp_error_or_bytes != PP_OK_COMPLETIONPENDING) + PP_RunCompletionCallback(&callback, pp_error_or_bytes); + } +} + +PP_Bool HandleDocumentLoad(PP_Instance instance, + PP_Resource url_loader) { + void* user_data = reinterpret_cast<void*>(url_loader); + PP_CompletionCallback callback = + PP_MakeOptionalCompletionCallback(ReadCallback, user_data); + int32_t pp_error_or_bytes = PPBURLLoader()->ReadResponseBody(url_loader, + buffer, + kMaxFileSize, + callback); + if (pp_error_or_bytes != PP_OK_COMPLETIONPENDING) + PP_RunCompletionCallback(&callback, pp_error_or_bytes); + return PP_TRUE; +} + +const PPP_Instance ppp_instance_interface = { + DidCreate, + DidDestroy, + DidChangeView, + DidChangeFocus, + HandleDocumentLoad +}; + +// This tests PPP_Instance::HandleDocumentLoad. +void TestHandleDocumentLoad() { + if (error_in_doc_load_line != kDocLoadErrorNone) { + char error[1024]; + snprintf(error, sizeof(error), + "ERROR at %s:%d: Document Load Failed\n", + __FILE__, error_in_doc_load_line); + fprintf(stderr, "%s", error); + PostTestMessage(__FUNCTION__, error); + } + TEST_PASSED; +} + +// This tests PPB_Instance::IsFullFrame when the plugin is full frame. +// Other conditions for IsFullFrame are tested by ppb_instance tests. +void TestIsFullFrame() { + PP_Bool full_frame = PPBInstance()->IsFullFrame(pp_instance()); + EXPECT(full_frame == PP_TRUE); + TEST_PASSED; +} + + +} // namespace + + +void SetupTests() { + RegisterTest("TestHandleDocumentLoad", TestHandleDocumentLoad); + RegisterTest("TestIsFullFrame", TestIsFullFrame); +} + +void SetupPluginInterfaces() { + RegisterPluginInterface(PPP_INSTANCE_INTERFACE, &ppp_instance_interface); +} diff --git a/ppapi/native_client/tests/ppapi_browser/extension_mime_handler/ppapi_extension_mime_handler.html b/ppapi/native_client/tests/ppapi_browser/extension_mime_handler/ppapi_extension_mime_handler.html new file mode 100644 index 0000000..278eb26 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/extension_mime_handler/ppapi_extension_mime_handler.html @@ -0,0 +1,45 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + <!-- Copyright 2011 Google Inc. All rights reserved. --> + <head> + <script type="text/javascript" src="nacltest.js"></script> + <script type="application/x-javascript"> + //<![CDATA[ + function iframe_loaded() { + var iframe_doc = window.frames['iframe_id'].document; + var iframe_body = iframe_doc.body; + var tester = new Tester(); + // 'plugin' is the name given to the embed by webkit + var plugin = iframe_doc.getElementsByName('plugin')[0]; + + function addTest(test_name, responses) { + if (responses === undefined) { + responses = []; + } + var expected_messages = [test_name + ':PASSED'].concat(responses); + tester.addAsyncTest(test_name, function(test) { + test.expectMessageSequence(plugin, expected_messages); + plugin.postMessage(test_name) + }); + } + + addTest('TestHandleDocumentLoad'); + addTest('TestIsFullFrame'); + tester.waitFor(plugin); + tester.run(); + } + //]]> + </script> + <title>PPAPI Extension MIME Type Test</title> + </head> + <body> + <h1>PPAPI Extension MIME Type Test</h1> + <iframe src='mime_test_data.pdf' + id='iframe_id' + width='100' + height='100' + onload='iframe_loaded()'> + </iframe> + </body> +</html> diff --git a/ppapi/native_client/tests/ppapi_browser/extension_mime_handler/ppapi_extension_mime_handler.nmf b/ppapi/native_client/tests/ppapi_browser/extension_mime_handler/ppapi_extension_mime_handler.nmf new file mode 100644 index 0000000..9fd22d4 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/extension_mime_handler/ppapi_extension_mime_handler.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_extension_mime_handler_x86-32.nexe"}, + "x86-64": {"url": "ppapi_extension_mime_handler_x86-64.nexe"}, + "arm": {"url": "ppapi_extension_mime_handler_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/manifest/manifest.html b/ppapi/native_client/tests/ppapi_browser/manifest/manifest.html new file mode 100644 index 0000000..bf7b0ec --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/manifest/manifest.html @@ -0,0 +1,70 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> +<!-- 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. --> +<head> + <title>PPAPI Runtime Feature Test</title> + <meta HTTP-EQUIV="Pragma" CONTENT="no-cache" /> + <meta HTTP-EQUIV="Expires" CONTENT="-1" /> + <script type="text/javascript" src="nacltest.js"></script> + <script type="text/javascript" src="ppapi_progress_events.js"></script> +</head> + +<body id="body"> +<script type="text/javascript"> +//<![CDATA[ +var tester = new Tester($('body')); +testProgressEventStateMachine( + tester, + 'topdir_static', + 2, // progressMinCount + 0, // errorCount + 0, // abortCount + 1, // loadCount + undefined // lastError +); +testProgressEventStateMachine( + tester, + 'subdir_static', + 2, // progressMinCount + 0, // errorCount + 0, // abortCount + 1, // loadCount + undefined // lastError +); +function runTests() { + tester.waitFor($('topdir_static'), $('subdir_static')); + tester.run(); +} +// Set all the listeners on the body. +setListeners($('body')); +//]]> +</script> + +<!-- +// manifest_top refers to nexes in a subdirectory below the manifest. +--> +<embed id="topdir_static" + class="naclModule" + width=0 height=0 + src="manifest_top.nmf" + type="application/x-nacl" /> + +<!-- +// manifest_subdir refers to resources in the same directory as the manifest. +--> +<embed id="subdir_static" + class="naclModule" + width=0 height=0 + src="subdir/manifest_subdir.nmf" + type="application/x-nacl" /> + +<script type="text/javascript"> +//<![CDATA[ +runTests(); +//]]> +</script> +</body> +</html> diff --git a/ppapi/native_client/tests/ppapi_browser/manifest/manifest_bad.cc b/ppapi/native_client/tests/ppapi_browser/manifest/manifest_bad.cc new file mode 100644 index 0000000..0832b76 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/manifest/manifest_bad.cc @@ -0,0 +1,40 @@ +// 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 <cstdio> +#include <cstdlib> +#include <cstring> + +#include "native_client/src/shared/platform/nacl_check.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/ppb.h" +#include "ppapi/c/ppp_instance.h" +#include "ppapi/c/dev/ppb_layer_compositor_dev.h" + +#include "ppapi/c/ppp.h" + +int32_t PPP_InitializeModule(PP_Module module_id, + PPB_GetInterface get_browser_interface) { + printf("PPP_InitializeModule\n"); + + // Request an unsupported interface. + CHECK(NULL == get_browser_interface(PPB_LAYER_COMPOSITOR_DEV_INTERFACE)); + // Request a supported interface with a bad revision number. + CHECK(NULL == get_browser_interface("PPB_Instance;0.0")); + + return PP_OK; +} + +PP_EXPORT void PPP_ShutdownModule() { + printf("PPP_ShutdownModule\n"); + fflush(stdout); +} + +PP_EXPORT const void* PPP_GetInterface(const char* interface_name) { + printf("PPP_GetInterface(%s)\n", interface_name); + if (0 == std::strcmp(interface_name, PPP_INSTANCE_INTERFACE)) // Required. + return NULL; + return NULL; +} diff --git a/ppapi/native_client/tests/ppapi_browser/manifest/manifest_good.cc b/ppapi/native_client/tests/ppapi_browser/manifest/manifest_good.cc new file mode 100644 index 0000000..aed22d5 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/manifest/manifest_good.cc @@ -0,0 +1,13 @@ +// 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/tests/ppapi_test_lib/test_interface.h" + +void SetupTests() { + // none +} + +void SetupPluginInterfaces() { + // none +} diff --git a/ppapi/native_client/tests/ppapi_browser/manifest/manifest_subdir.nmf b/ppapi/native_client/tests/ppapi_browser/manifest/manifest_subdir.nmf new file mode 100644 index 0000000..65fd88d --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/manifest/manifest_subdir.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "manifest_good_x86-32.nexe"}, + "x86-64": {"url": "manifest_good_x86-64.nexe"}, + "arm": {"url": "manifest_good_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/manifest/manifest_top.nmf b/ppapi/native_client/tests/ppapi_browser/manifest/manifest_top.nmf new file mode 100644 index 0000000..dcbf573 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/manifest/manifest_top.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "subdir/manifest_good_x86-32.nexe"}, + "x86-64": {"url": "subdir/manifest_good_x86-64.nexe"}, + "arm": {"url": "subdir/manifest_good_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/manifest/nacl.scons b/ppapi/native_client/tests/ppapi_browser/manifest/nacl.scons new file mode 100644 index 0000000..27a28ae --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/manifest/nacl.scons @@ -0,0 +1,63 @@ +# -*- python -*- +# 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. + +Import('env') + +# TODO(robertm): those should not be necessary once we go -std=c99 +env.FilterOut(CFLAGS=['-pedantic']) +env.FilterOut(CCFLAGS=['-pedantic']) + +manifest_good_sources = env.ComponentObject('manifest_good.cc'), + +manifest_good_target = ('manifest_good_%s' % + env.get('TARGET_FULLARCH')) +env.ComponentProgram(manifest_good_target, + [manifest_good_sources], + EXTRA_LIBS=['${PPAPI_LIBS}', + 'ppapi_test_lib', + 'pthread', + 'platform', + 'gio']) + +manifest_bad_sources = env.ComponentObject('manifest_bad.cc'), + +manifest_bad_target = ('manifest_bad_%s' % + env.get('TARGET_FULLARCH')) +env.ComponentProgram(manifest_bad_target, + [manifest_bad_sources], + EXTRA_LIBS=['${PPAPI_LIBS}', + 'ppapi_test_lib', + 'pthread', + 'platform', + 'gio']) + +env.Publish(manifest_good_target, 'run', [ + 'manifest.html', + manifest_bad_target, + 'manifest_top.nmf', + 'manifest_subdir.nmf', + ('${SCONSTRUCT_DIR}/tests/ppapi_browser/progress_events/' + + 'ppapi_progress_events.js'), + '${SCONSTRUCT_DIR}/tools/browser_tester/browserdata/nacltest.js', +]) + +node = env.PPAPIBrowserTester( + 'manifest_browser_test.out', + url='manifest.html', + files=env.ExtractPublishedFiles(manifest_good_target), + map_files=[ + ('subdir/manifest_subdir.nmf', + env.File('${STAGING_DIR}/manifest_subdir.nmf')), + # the 'good' nexe in the root directory will fail. + (manifest_good_target + env['PROGSUFFIX'], + env.File('${STAGING_DIR}/%s${PROGSUFFIX}' % manifest_bad_target)), + # the 'good' nexe in the subdirectory will succeed. + ('subdir/' + manifest_good_target + env['PROGSUFFIX'], + env.File('${STAGING_DIR}/%s${PROGSUFFIX}' % manifest_good_target))]) + +env.AddNodeToTestSuite(node, + ['chrome_browser_tests'], + 'run_manifest_browser_test', + is_broken=env.PPAPIBrowserTesterIsBroken()) diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_core/nacl.scons b/ppapi/native_client/tests/ppapi_browser/ppb_core/nacl.scons new file mode 100644 index 0000000..eb6aa92 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_core/nacl.scons @@ -0,0 +1,38 @@ +# -*- python -*- +# 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. +# +# This test uses ppapi_test_lib. + +Import('env') + +env.Prepend(CPPDEFINES=['XP_UNIX']) + +nexe = 'ppapi_ppb_core_%s' % env.get('TARGET_FULLARCH') +env.Alias('ppapi_ppb_core${PROGSUFFIX}', ['$STAGING_DIR/%s${PROGSUFFIX}' % nexe]) + +env.ComponentProgram( + nexe, + ['ppapi_ppb_core.cc'], + EXTRA_LIBS=['${PPAPI_LIBS}', + 'ppapi_test_lib', + 'pthread', + 'platform', + 'gio']) + +# Note that the html is required to run this program. +env.Publish(nexe, 'run', + ['ppapi_ppb_core.html', + 'ppapi_ppb_core.nmf', + env.File('${SCONSTRUCT_DIR}/tools/browser_tester/' + 'browserdata/nacltest.js')]) + +node = env.PPAPIBrowserTester('ppapi_ppb_core_browser_test.out', + url='ppapi_ppb_core.html', + files=env.ExtractPublishedFiles(nexe)) + +env.AddNodeToTestSuite(node, + ['chrome_browser_tests'], + 'run_ppapi_ppb_core_browser_test', + is_broken=env.PPAPIBrowserTesterIsBroken()) diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_core/ppapi_ppb_core.cc b/ppapi/native_client/tests/ppapi_browser/ppb_core/ppapi_ppb_core.cc new file mode 100644 index 0000000..31623fa --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_core/ppapi_ppb_core.cc @@ -0,0 +1,247 @@ +// 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 <pthread.h> +#include <stdio.h> +#include <string.h> + +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/tests/ppapi_test_lib/get_browser_interface.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" + +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/ppb_core.h" +#include "ppapi/c/ppb_url_request_info.h" + +namespace { + +const int32_t kNotPPError = 12345; +const int kStressChecksum = 0x12345678; + +void EmptyCompletionCallback(void* data, int32_t /*result*/) { + CHECK(data == NULL); +} + +// Calls PPB_Core::CallOnMainThread(). To be invoked off the main thread. +void* InvokeCallOnMainThread(void* thread_argument) { + PPB_Core* ppb_core = reinterpret_cast<PPB_Core*>(thread_argument); + PP_CompletionCallback callback = MakeTestableCompletionCallback( + "CallOnMainThreadCallback_FromNonMainThread", + EmptyCompletionCallback, + NULL /*user_data*/); + ppb_core->CallOnMainThread(0 /*delay*/, callback, PP_OK); + return NULL; +} + +struct StressData { + const PPB_Core* ppb_core_; + const int callbacks_per_thread_; + int callback_counter_; + const int checksum_; + StressData(const PPB_Core* ppb_core, int callbacks_per_thread, int total) + : ppb_core_(ppb_core), + callbacks_per_thread_(callbacks_per_thread), + callback_counter_(total), + checksum_(kStressChecksum) { + } +}; + +// When passed in stress->callback_counter_ reaches zero, notify JS via +// MakeTestableCompletionCallback. +void ThreadStressCompletionCallback(void* data, int32_t result) { + if (PP_OK == result) { + StressData* stress = reinterpret_cast<StressData*>(data); + CHECK(kStressChecksum == stress->checksum_); + CHECK(NULL != stress->ppb_core_); + stress->callback_counter_ -= 1; + if (0 == stress->callback_counter_) { + // All the callbacks triggered, so now report back that this test passed. + PP_CompletionCallback callback = MakeTestableCompletionCallback( + "CallOnMainThreadCallback_ThreadStress", + EmptyCompletionCallback, NULL); + stress->ppb_core_->CallOnMainThread(0, callback, PP_OK); + // At this point we're done with the structure, so set it to zero. + // If anyone from here on out tries to access it, either the pointer + // check or the checksum should trip. It is intentionally left on the + // heap to prevent re-use of the memory. + memset(stress, 0, sizeof(*stress)); + } + } +} + +// Calls PPB_Core::CallOnMainThread(). To be invoked off the main thread. +// This is a stess test version. +void* InvokeCallOnMainThreadStress(void* thread_argument) { + StressData* stress = reinterpret_cast<StressData*>(thread_argument); + PP_CompletionCallback callback = PP_MakeCompletionCallback( + ThreadStressCompletionCallback, stress); + for (int i = 0; i < stress->callbacks_per_thread_; ++i) { + CHECK(NULL != stress->ppb_core_); + CHECK(kStressChecksum == stress->checksum_); + stress->ppb_core_->CallOnMainThread(0, callback, PP_OK); + } + return NULL; +} + +// Calls PPB_Core::IsMainThread(). To be invoked off the main thread. +void* InvokeIsMainThread(void* thread_argument) { + PPB_Core* ppb_core = reinterpret_cast<PPB_Core*>(thread_argument); + return reinterpret_cast<void*>(ppb_core->IsMainThread()); +} + +// Tests PPB_Core::GetTime(). +void TestGetTime() { + PP_Time time1 = PPBCore()->GetTime(); + EXPECT(time1 > 0); + + usleep(100000); // 0.1 second + + PP_Time time2 = PPBCore()->GetTime(); + EXPECT(time2 > time1); + + TEST_PASSED; +} + +// Tests PPB_Core::GetTimeTicks(). +void TestGetTimeTicks() { + PP_TimeTicks time_ticks1 = PPBCore()->GetTimeTicks(); + EXPECT(time_ticks1 > 0); + + usleep(100000); // 0.1 second + + PP_TimeTicks time_ticks2 = PPBCore()->GetTimeTicks(); + EXPECT(time_ticks2 > time_ticks1); + + TEST_PASSED; +} + +// Tests PPB_Core::CallOnMainThread() from the main thread. +void TestCallOnMainThread_FromMainThread() { + PP_CompletionCallback callback = MakeTestableCompletionCallback( + "CallOnMainThreadCallback_FromMainThread", + EmptyCompletionCallback, + NULL /*user_data*/); + PPBCore()->CallOnMainThread(0 /*delay*/, callback, kNotPPError); + + TEST_PASSED; +} + +// Tests PPB_Core::CallOnMainThread() from the main thread after a long delay. +// This is useful for surf-away/reload tests where the nexe is aborted +// after the callback was scheduled, but before it was fired. +void TestCallOnMainThread_FromMainThreadDelayed() { + PP_CompletionCallback callback = MakeTestableCompletionCallback( + "CallOnMainThreadCallback_FromMainThreadDelayed", + EmptyCompletionCallback, + NULL /*user_data*/); + PPBCore()->CallOnMainThread(1000 /*delay in ms*/, callback, kNotPPError); + + TEST_PASSED; +} + +// Tests PPB_Core::CallOnMainThread from non-main thread. +void TestCallOnMainThread_FromNonMainThread() { + pthread_t tid; + void* ppb_core = reinterpret_cast<void*>(const_cast<PPB_Core*>(PPBCore())); + CHECK(pthread_create(&tid, NULL, InvokeCallOnMainThread, ppb_core) == 0); + // Use a non-joined thread. This is a more useful test than + // joining the thread: we want to test CallOnMainThread() when it + // is called concurrently with the main thread. + CHECK(pthread_detach(tid) == 0); + + TEST_PASSED; +} + +// Tests PPB_Core::CallOnMainThread from non-main thread. +// This is a stress test version that calls many times from many threads. +void TestCallOnMainThread_FromNonMainThreadStress() { + const int kNumThreads = 10; + const int kNumPerThread = 100; + const int kNumCallbacks = kNumThreads * kNumPerThread; + StressData* stress = new StressData(PPBCore(), kNumPerThread, kNumCallbacks); + for (int i = 0; i < kNumThreads; ++i) { + pthread_t tid; + CHECK(pthread_create( + &tid, NULL, InvokeCallOnMainThreadStress, stress) == 0); + CHECK(pthread_detach(tid) == 0); + } + TEST_PASSED; +} + +// Tests PPB_Core::IsMainThread() from the main thread. +void TestIsMainThread_FromMainThread() { + EXPECT(PPBCore()->IsMainThread() == PP_TRUE); + TEST_PASSED; +} + +// Tests PPB_Core::IsMainThread() from non-main thread. +void TestIsMainThread_FromNonMainThread() { + pthread_t tid; + void* thread_result; + void* ppb_core = reinterpret_cast<void*>(const_cast<PPB_Core*>(PPBCore())); + CHECK(pthread_create(&tid, NULL, InvokeIsMainThread, ppb_core) == 0); + CHECK(pthread_join(tid, &thread_result) == 0); + EXPECT(reinterpret_cast<int>(thread_result) == PP_FALSE); + + TEST_PASSED; +} + + +// Tests PPB_Core::AddRefResource() and PPB_Core::ReleaseResource() with +// a valid resource. +void TestAddRefAndReleaseResource() { + PP_Resource valid_resource = PPBURLRequestInfo()->Create(pp_instance()); + EXPECT(valid_resource != kInvalidResource); + EXPECT(PPBURLRequestInfo()->IsURLRequestInfo(valid_resource) == PP_TRUE); + + // Adjusting ref count should not delete the resource. + for (size_t j = 0; j < 100; ++j) PPBCore()->AddRefResource(valid_resource); + EXPECT(PPBURLRequestInfo()->IsURLRequestInfo(valid_resource) == PP_TRUE); + for (size_t j = 0; j < 100; ++j) PPBCore()->ReleaseResource(valid_resource); + EXPECT(PPBURLRequestInfo()->IsURLRequestInfo(valid_resource) == PP_TRUE); + + // Releasing the ref count from Create() must delete the resource. + PPBCore()->ReleaseResource(valid_resource); + EXPECT(PPBURLRequestInfo()->IsURLRequestInfo(valid_resource) != PP_TRUE); + + TEST_PASSED; +} + +// Tests PPB_Core::AddRefResource() and PPB_Core::ReleaseResource() with +// an invalid resource. +void TestAddRefAndReleaseInvalidResource() { + for (size_t j = 0; j < 100; ++j) { + PPBCore()->AddRefResource(kInvalidResource); + PPBCore()->ReleaseResource(kInvalidResource); + } + + TEST_PASSED; +} + +} // namespace + +void SetupTests() { + RegisterTest("TestGetTime", TestGetTime); + RegisterTest("TestGetTimeTicks", TestGetTimeTicks); + RegisterTest("TestIsMainThread_FromMainThread", + TestIsMainThread_FromMainThread); + RegisterTest("TestIsMainThread_FromNonMainThread", + TestIsMainThread_FromNonMainThread); + RegisterTest("TestAddRefAndReleaseResource", + TestAddRefAndReleaseResource); + RegisterTest("TestAddRefAndReleaseInvalidResource", + TestAddRefAndReleaseInvalidResource); + RegisterTest("TestCallOnMainThread_FromMainThread", + TestCallOnMainThread_FromMainThread); + RegisterTest("TestCallOnMainThread_FromMainThreadDelayed", + TestCallOnMainThread_FromMainThreadDelayed); + RegisterTest("TestCallOnMainThread_FromNonMainThread", + TestCallOnMainThread_FromNonMainThread); + RegisterTest("TestCallOnMainThread_FromNonMainThreadStress", + TestCallOnMainThread_FromNonMainThreadStress); +} + +void SetupPluginInterfaces() { + // none +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_core/ppapi_ppb_core.html b/ppapi/native_client/tests/ppapi_browser/ppb_core/ppapi_ppb_core.html new file mode 100644 index 0000000..797b16c --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_core/ppapi_ppb_core.html @@ -0,0 +1,65 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + <!-- Copyright 2011 Google Inc. All rights reserved. --> + <head> + <META HTTP-EQUIV="Pragma" CONTENT="no-cache" /> + <META HTTP-EQUIV="Expires" CONTENT="-1" /> + <script type="text/javascript" src="nacltest.js"></script> + <script type="application/x-javascript"> + //<![CDATA[ + function setupTests(tester, plugin) { + function addTest(test_name, responses) { + if (responses === undefined) { + responses = []; + } + var expected_messages = [test_name + ':PASSED'].concat(responses); + tester.addAsyncTest('PPB_Core::' + test_name, function(test) { + test.expectMessageSequence(plugin, expected_messages); + plugin.postMessage(test_name) + }); + } + + // Off the main thread. + // Doing these tests first will check that the proxy is properly + // caching the interface pointers on the main thread on initialization. + addTest('TestCallOnMainThread_FromNonMainThread', + ['CallOnMainThreadCallback_FromNonMainThread']); + addTest('TestCallOnMainThread_FromNonMainThreadStress', + ['CallOnMainThreadCallback_ThreadStress']); + + // On the main thread. + addTest('TestGetTime'); + addTest('TestGetTimeTicks'); + addTest('TestIsMainThread_FromMainThread'); + addTest('TestIsMainThread_FromNonMainThread'); + addTest('TestAddRefAndReleaseResource'); + addTest('TestAddRefAndReleaseInvalidResource'); + addTest('TestCallOnMainThread_FromMainThread', + ['CallOnMainThreadCallback_FromMainThread']); + addTest('TestCallOnMainThread_FromMainThreadDelayed', + ['CallOnMainThreadCallback_FromMainThreadDelayed']); + + } + //]]> + </script> + <title>PPAPI PPB_Core Test</title> + </head> + <body> + <h1>PPAPI PPB_Core Test</h1> + + <embed type="application/x-nacl" id="test_nexe" + name="nacl_module" + src="ppapi_ppb_core.nmf" + width="0" height="0" /> + + <script type="text/javascript"> + //<![CDATA[ + var tester = new Tester(); + setupTests(tester, $('test_nexe')); + tester.waitFor($('test_nexe')); + tester.run(); + //]]> + </script> + </body> +</html> diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_core/ppapi_ppb_core.nmf b/ppapi/native_client/tests/ppapi_browser/ppb_core/ppapi_ppb_core.nmf new file mode 100644 index 0000000..0db3b00 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_core/ppapi_ppb_core.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_ppb_core_x86-32.nexe"}, + "x86-64": {"url": "ppapi_ppb_core_x86-64.nexe"}, + "arm": {"url": "ppapi_ppb_core_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_dev/nacl.scons b/ppapi/native_client/tests/ppapi_browser/ppb_dev/nacl.scons new file mode 100644 index 0000000..a07e0ee --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_dev/nacl.scons @@ -0,0 +1,40 @@ +# -*- python -*- +# 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. +# +# This test uses ppapi_test_lib. + +Import('env') + +env.Prepend(CPPDEFINES=['XP_UNIX']) + +nexe = 'ppapi_ppb_dev_${TARGET_FULLARCH}' +env.Alias('ppapi_ppb_dev${PROGSUFFIX}', + ['$STAGING_DIR/%s${PROGSUFFIX}' % nexe]) + +env.ComponentProgram( + nexe, + ['ppapi_ppb_dev.cc'], + EXTRA_LIBS=['${PPAPI_LIBS}', + 'ppapi_test_lib', + 'platform', # for CHECK + 'pthread', + 'gio', + ]) + +env.Publish(nexe, 'run', + [ 'ppapi_ppb_dev.html', + 'ppapi_ppb_dev.nmf', + env.File('${SCONSTRUCT_DIR}/tools/browser_tester/' + 'browserdata/nacltest.js') ]) + +node = env.PPAPIBrowserTester('ppapi_ppb_dev_browser_test.out', + url='ppapi_ppb_dev.html', + files=env.ExtractPublishedFiles(nexe), + args=['--enable_ppapi_dev=0']) + +env.AddNodeToTestSuite(node, + ['chrome_browser_tests'], + 'run_ppapi_ppb_dev_browser_test', + is_broken=env.PPAPIBrowserTesterIsBroken()) diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_dev/ppapi_ppb_dev.cc b/ppapi/native_client/tests/ppapi_browser/ppb_dev/ppapi_ppb_dev.cc new file mode 100644 index 0000000..1362a97 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_dev/ppapi_ppb_dev.cc @@ -0,0 +1,95 @@ +// 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. +// +// Test cases for PPAPI Dev interfaces. +// + +#include <string.h> + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/src/shared/ppapi_proxy/plugin_nacl_file.h" +#include "native_client/tests/ppapi_test_lib/get_browser_interface.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" +#include "ppapi/c/pp_bool.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/ppb_core.h" + +#include "ppapi/c/dev/ppb_buffer_dev.h" +#include "ppapi/c/dev/ppb_char_set_dev.h" +#include "ppapi/c/dev/ppb_console_dev.h" +#include "ppapi/c/dev/ppb_context_3d_dev.h" +#include "ppapi/c/dev/ppb_context_3d_trusted_dev.h" +#include "ppapi/c/dev/ppb_crypto_dev.h" +#include "ppapi/c/dev/ppb_cursor_control_dev.h" +#include "ppapi/c/dev/ppb_directory_reader_dev.h" +#include "ppapi/c/dev/ppb_file_chooser_dev.h" +#include "ppapi/c/dev/ppb_find_dev.h" +#include "ppapi/c/dev/ppb_font_dev.h" +#include "ppapi/c/dev/ppb_fullscreen_dev.h" +#include "ppapi/c/dev/ppb_gles_chromium_texture_mapping_dev.h" +#include "ppapi/c/dev/ppb_graphics_3d_dev.h" +#include "ppapi/c/dev/ppb_layer_compositor_dev.h" +#include "ppapi/c/dev/ppb_memory_dev.h" +#include "ppapi/c/dev/ppb_opengles_dev.h" +#include "ppapi/c/dev/ppb_scrollbar_dev.h" +#include "ppapi/c/dev/ppb_surface_3d_dev.h" +#include "ppapi/c/dev/ppb_testing_dev.h" +#include "ppapi/c/dev/ppb_transport_dev.h" +#include "ppapi/c/dev/ppb_url_util_dev.h" +#include "ppapi/c/dev/ppb_var_deprecated.h" +#include "ppapi/c/dev/ppb_video_decoder_dev.h" +#include "ppapi/c/dev/ppb_widget_dev.h" +#include "ppapi/c/dev/ppb_zoom_dev.h" + + +namespace { + +//////////////////////////////////////////////////////////////////////////////// +// Test Cases +//////////////////////////////////////////////////////////////////////////////// + +void TestGetDevInterfaces() { + // This test is run only w/ NACL_ENABLE_PPAPI_DEV=0, which should + // turn off and disable the PPAPI developer interfaces. When they are + // disabled, the interface should return NULL. + CHECK(GetBrowserInterface(PPB_BUFFER_DEV_INTERFACE) == NULL); + CHECK(GetBrowserInterface(PPB_CHAR_SET_DEV_INTERFACE) == NULL); + CHECK(GetBrowserInterface(PPB_CONSOLE_DEV_INTERFACE) == NULL); + CHECK(GetBrowserInterface(PPB_CONTEXT_3D_DEV_INTERFACE) == NULL); + CHECK(GetBrowserInterface(PPB_CRYPTO_DEV_INTERFACE) == NULL); + CHECK(GetBrowserInterface(PPB_CURSOR_CONTROL_DEV_INTERFACE) == NULL); + CHECK(GetBrowserInterface(PPB_DIRECTORYREADER_DEV_INTERFACE) == NULL); + CHECK(GetBrowserInterface(PPB_FILECHOOSER_DEV_INTERFACE) == NULL); + CHECK(GetBrowserInterface(PPB_FIND_DEV_INTERFACE) == NULL); + CHECK(GetBrowserInterface(PPB_FONT_DEV_INTERFACE) == NULL); + CHECK(GetBrowserInterface(PPB_FULLSCREEN_DEV_INTERFACE) == NULL); + CHECK(GetBrowserInterface( + PPB_GLES_CHROMIUM_TEXTURE_MAPPING_DEV_INTERFACE) == NULL); + CHECK(GetBrowserInterface(PPB_GRAPHICS_3D_DEV_INTERFACE) == NULL); + CHECK(GetBrowserInterface(PPB_LAYER_COMPOSITOR_DEV_INTERFACE) == NULL); + CHECK(GetBrowserInterface(PPB_MEMORY_DEV_INTERFACE) == NULL); + CHECK(GetBrowserInterface(PPB_OPENGLES2_DEV_INTERFACE) == NULL); + CHECK(GetBrowserInterface(PPB_SCROLLBAR_DEV_INTERFACE) == NULL); + CHECK(GetBrowserInterface(PPB_SURFACE_3D_DEV_INTERFACE) == NULL); + CHECK(GetBrowserInterface(PPB_TESTING_DEV_INTERFACE) == NULL); + CHECK(GetBrowserInterface(PPB_TRANSPORT_DEV_INTERFACE) == NULL); + CHECK(GetBrowserInterface(PPB_URLUTIL_DEV_INTERFACE) == NULL); + CHECK(GetBrowserInterface(PPB_VAR_DEPRECATED_INTERFACE) == NULL); + CHECK(GetBrowserInterface(PPB_VIDEODECODER_DEV_INTERFACE) == NULL); + CHECK(GetBrowserInterface(PPB_WIDGET_DEV_INTERFACE) == NULL); + CHECK(GetBrowserInterface(PPB_ZOOM_DEV_INTERFACE) == NULL); + + TEST_PASSED; +} + +} // namespace + +void SetupTests() { + RegisterTest("TestGetDevInterfaces", TestGetDevInterfaces); +} + +void SetupPluginInterfaces() { + // none +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_dev/ppapi_ppb_dev.html b/ppapi/native_client/tests/ppapi_browser/ppb_dev/ppapi_ppb_dev.html new file mode 100644 index 0000000..b65a159 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_dev/ppapi_ppb_dev.html @@ -0,0 +1,57 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + <!-- Copyright (c) 2011 Google Inc. All rights reserved. --> + <head> + <META HTTP-EQUIV="Pragma" CONTENT="no-cache" /> + <META HTTP-EQUIV="Expires" CONTENT="-1" /> + <script type="text/javascript" src="nacltest.js"></script> + <script type="application/x-javascript"> +//<![CDATA[ +function setupTests(tester, plugin) { + function testAndAssertStatus(test, name, status) { + var messageListener = test.wrap(function(message) { + plugin.removeEventListener('message', messageListener, false); + test.assertEqual(message.data, name + ':' + status); + test.pass(); + }); + plugin.addEventListener('message', messageListener, false); + plugin.postMessage(name); + } + + tester.addAsyncTest('PPB_Dev::GetDevInterfaces', + function(test) { + testAndAssertStatus(test, 'TestGetDevInterfaces', 'PASSED'); + } + ); +} +//]]> + </script> + <title>PPAPI Dev Interface Test</title> + </head> + <body> + <h1>PPAPI Dev Interface Test</h1> + NOTE: requires --enable-pepper-testing. Also, this test should be run with + PPAPI Dev interfaces disabled; the environment variable NACL_ENABLE_PPAPI_DEV + should be set to 0 or unset. + <br><br> + <table> + <tr> + <td> + <embed type="application/x-nacl" id="test_nexe" + name="nacl_module" + src="ppapi_ppb_dev.nmf" + style="background-color:#FFFFFF" + width="90" height="90" /> + <table> + <br> + <script type="text/javascript"> + //<![CDATA[ + var tester = new Tester(); + setupTests(tester, $('test_nexe')); + tester.waitFor($('test_nexe')); + tester.run(); + //]]> + </script> + </body> +</html> diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_dev/ppapi_ppb_dev.nmf b/ppapi/native_client/tests/ppapi_browser/ppb_dev/ppapi_ppb_dev.nmf new file mode 100644 index 0000000..37180ae --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_dev/ppapi_ppb_dev.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_ppb_dev_x86-32.nexe"}, + "x86-64": {"url": "ppapi_ppb_dev_x86-64.nexe"}, + "arm": {"url": "ppapi_ppb_dev_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_file_io/common.cc b/ppapi/native_client/tests/ppapi_browser/ppb_file_io/common.cc new file mode 100644 index 0000000..d04679b --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_file_io/common.cc @@ -0,0 +1,183 @@ +// 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/tests/ppapi_browser/ppb_file_io/common.h" + +#include <string.h> +#include <string> + +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/src/third_party/ppapi/c/pp_errors.h" +#include "native_client/src/third_party/ppapi/c/ppb_core.h" +#include "native_client/src/third_party/ppapi/c/ppb_file_io.h" +#include "native_client/src/third_party/ppapi/c/ppb_file_ref.h" +#include "native_client/src/third_party/ppapi/c/ppb_file_system.h" +#include "native_client/src/third_party/ppapi/c/ppb_messaging.h" +#include "native_client/src/third_party/ppapi/c/ppb_url_loader.h" +#include "native_client/src/third_party/ppapi/c/ppb_var.h" +#include "native_client/tests/ppapi_test_lib/get_browser_interface.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" + +namespace common { + +const char* kTestData = + "Everywhere is within walking distance if you have the time"; + +void InitFileInfo(PP_FileSystemType system_type, PP_FileInfo* file_info) { + memset(file_info, 0, sizeof(PP_FileInfo)); + file_info->system_type = system_type; + file_info->type = PP_FILETYPE_REGULAR; + file_info->last_access_time = 200; // dummy value + file_info->last_modified_time = 100; // something less than last access time +} + +BoundPPAPIFunc OpenFileForTest::GetCompletionCallbackInitiatingPPAPIFunction( + TestCallbackData* callback_data) { + return std::tr1::bind(PPBFileIO()->Open, + callback_data->existing_file_io, + callback_data->existing_file_ref, + PP_FILEOPENFLAG_READ | PP_FILEOPENFLAG_WRITE, + std::tr1::placeholders::_1); +} + +void FileIOTester::AddSequenceElement(TestSequenceElement* element) { + test_sequence_.push_back(element); +} + +void FileIOTester::Run() { + if (test_sequence_.empty()) + return; + + PP_Resource file_system = PPBFileSystem()->Create(pp_instance(), + file_info_.system_type); + EXPECT(file_system != kInvalidResource); + + TestCallbackData* callback_data = new TestCallbackData(file_system, + file_info_, + test_sequence_); + + int32_t pp_error = PPBFileSystem()->Open( + callback_data->file_system, + 1024, + MakeTestableCompletionCallback( + "OpenFileSystemForSetupCallback", + OpenFileSystemForSetupCallback, + callback_data)); + EXPECT(pp_error == PP_OK_COMPLETIONPENDING); +} + +void FileIOTester::FlushFileForSetupCallback(void* data, int32_t result) { + // This callback should be preceded by a write operation. + EXPECT(result >= PP_OK); + + TestCallbackData* callback_data = reinterpret_cast<TestCallbackData*>(data); + PP_FileInfo file_info = callback_data->file_info; + int32_t pp_error = PPBFileIO()->Touch(callback_data->existing_file_io, + file_info.last_access_time, + file_info.last_modified_time, + MakeTestableCompletionCallback( + "TouchFileForSetupCallback", + TouchFileForSetupCallback, + callback_data)); + EXPECT(pp_error == PP_OK_COMPLETIONPENDING); +} + +// This is the first callback in the chain of callbacks. The first several in +// the chain are initialization for the tests that come later in the chain. +void FileIOTester::OpenFileSystemForSetupCallback(void* data, int32_t result) { + EXPECT(result == PP_OK); + + // Need to retrieve file system from the data in order to create file ref + TestCallbackData* callback_data = reinterpret_cast<TestCallbackData*>(data); + const PP_Resource file_system = callback_data->file_system; + // Create file ref for non-existing file + callback_data->non_existing_file_ref = PPBFileRef()->Create( + file_system, + "/non_existing_file"); + EXPECT(callback_data->non_existing_file_ref != kInvalidResource); + + // Create file io for non-existing file + callback_data->non_existing_file_io = PPBFileIO()->Create(pp_instance()); + EXPECT(callback_data->non_existing_file_io != kInvalidResource); + + // Create file ref for existing file + callback_data->existing_file_ref = PPBFileRef()->Create(file_system, + "/existing_file"); + EXPECT(callback_data->existing_file_ref != kInvalidResource); + + // Create file io for existing file + callback_data->existing_file_io = PPBFileIO()->Create(pp_instance()); + EXPECT(callback_data->existing_file_io != kInvalidResource); + + const PP_FileInfo& file_info = callback_data->file_info; + if (file_info.type == PP_FILETYPE_REGULAR) { + int32_t pp_error = PPBFileIO()->Open(callback_data->existing_file_io, + callback_data->existing_file_ref, + PP_FILEOPENFLAG_TRUNCATE | + PP_FILEOPENFLAG_CREATE | + PP_FILEOPENFLAG_WRITE, + MakeTestableCompletionCallback( + "OpenFileForSetupCallback", + OpenFileForSetupCallback, + callback_data)); + EXPECT(pp_error == PP_OK_COMPLETIONPENDING); + } else if (file_info.type == PP_FILETYPE_DIRECTORY) { + // TODO(sanga): Log a message indicating directories are not yet supported + // in these tests. + } +} + +void FileIOTester::OpenFileForSetupCallback(void* data, int32_t result) { + EXPECT(result == PP_OK); + + TestCallbackData* callback_data = reinterpret_cast<TestCallbackData*>(data); + PP_FileInfo file_info = callback_data->file_info; + int32_t pp_error = PPBFileIO()->Write(callback_data->existing_file_io, + 0, // no offset + kTestData, + strlen(kTestData), + MakeTestableCompletionCallback( + "WriteFileForSetupCallback", + WriteFileForSetupCallback, + callback_data)); + EXPECT(pp_error == PP_OK_COMPLETIONPENDING); +} + +void FileIOTester::StartTestSequence(TestCallbackData* callback_data) { + if (!callback_data->test_sequence.empty()) { + TestSequenceElement* first_test_element = + callback_data->test_sequence.front(); + PP_CompletionCallback callback = MakeTestableCompletionCallback( + first_test_element->name(), + TestSequenceElement::TestSequenceElementForwardingCallback, + callback_data); + PPBCore()->CallOnMainThread(0, // no delay + callback, PP_OK); + } else { + TestSequenceElement::CleanupResources(callback_data); + } +} + +// Assign testing file properties with data from given callback data. +void FileIOTester::TouchFileForSetupCallback(void* data, int32_t result) { + EXPECT(result == PP_OK); + + TestCallbackData* callback_data = reinterpret_cast<TestCallbackData*>(data); + PPBFileIO()->Close(callback_data->existing_file_io); + StartTestSequence(callback_data); +} + +void FileIOTester::WriteFileForSetupCallback(void* data, int32_t result) { + EXPECT(result >= PP_OK); + + TestCallbackData* callback_data = reinterpret_cast<TestCallbackData*>(data); + int32_t pp_error = PPBFileIO()->Flush(callback_data->existing_file_io, + MakeTestableCompletionCallback( + "FlushFileForSetupCallback", + FlushFileForSetupCallback, + callback_data)); + EXPECT(pp_error == PP_OK_COMPLETIONPENDING); +} + +} // namespace common diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_file_io/common.h b/ppapi/native_client/tests/ppapi_browser/ppb_file_io/common.h new file mode 100644 index 0000000..4f414b1 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_file_io/common.h @@ -0,0 +1,61 @@ +// 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. +#ifndef NATIVE_CLIENT_TESTS_PPAPI_BROWSER_PPB_FILE_IO_COMMON_H_ +#define NATIVE_CLIENT_TESTS_PPAPI_BROWSER_PPB_FILE_IO_COMMON_H_ + +#include <deque> + +#include "native_client/src/third_party/ppapi/c/pp_file_info.h" +#include "native_client/tests/ppapi_browser/ppb_file_io/test_sequence_element.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" + +namespace common { + +extern const char* kTestData; + +// Open file for subsequent tests. +class OpenFileForTest : public TestSequenceElement { + public: + OpenFileForTest() + : TestSequenceElement("OpenFileForTest") {} + + private: + virtual BoundPPAPIFunc GetCompletionCallbackInitiatingPPAPIFunction( + TestCallbackData* callback_data); +}; + +// Initializes the member data of given file info to either known values, (e.g. +// file system type), or dummy values (e.g. last modified time). +void InitFileInfo(PP_FileSystemType system_type, PP_FileInfo* file_info); + +// TODO(sanga): Move this to file_io_tester.h +// FileIOTester is the test runner. Used to accrue a sequence of test elements +// in a specific order and run the sequence. +class FileIOTester { + public: + explicit FileIOTester(const PP_FileInfo& file_info) + : file_info_(file_info) {} + ~FileIOTester() {} + + void AddSequenceElement(TestSequenceElement* element); // sink + void Run(); + + private: + // Callbacks for setting up before executing the test sequence. + static void FlushFileForSetupCallback(void* data, int32_t result); + static void OpenFileForSetupCallback(void* data, int32_t result); + static void OpenFileSystemForSetupCallback(void* data, int32_t result); + static void StartTestSequence(TestCallbackData* callback_data); + static void TouchFileForSetupCallback(void* data, int32_t result); + static void WriteFileForSetupCallback(void* data, int32_t result); + + const PP_FileInfo file_info_; + std::deque<TestSequenceElement*> test_sequence_; + + DISALLOW_COPY_AND_ASSIGN(FileIOTester); +}; + +} // namespace common + +#endif // NATIVE_CLIENT_TESTS_PPAPI_BROWSER_PPB_FILE_IO_COMMON_H_ diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_file_io/nacl.scons b/ppapi/native_client/tests/ppapi_browser/ppb_file_io/nacl.scons new file mode 100644 index 0000000..28ef8ef --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_file_io/nacl.scons @@ -0,0 +1,42 @@ +# -*- python -*- +# 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. +# +# This test uses ppapi_test_lib. + +Import('env') + +env.Prepend(CPPDEFINES=['XP_UNIX']) + +nexe = 'ppapi_ppb_file_io_%s' % env.get('TARGET_FULLARCH') +env.Alias('ppapi_ppb_file_io${PROGSUFFIX}', + ['$STAGING_DIR/%s${PROGSUFFIX}' % nexe]) + +env.ComponentProgram(nexe, + ['common.cc', + 'test_open.cc', + 'test_read.cc', + 'test_query.cc', + 'test_sequence_element.cc', + 'ppapi_ppb_file_io.cc'], + EXTRA_LIBS=['${PPAPI_LIBS}', + 'ppapi_test_lib', + 'platform', + 'pthread', + 'gio']) + +env.Publish(nexe, 'run', + ['ppapi_ppb_file_io.html', + 'ppapi_ppb_file_io.nmf', + 'ppapi_ppb_file_io.js']) + +node = env.PPAPIBrowserTester('ppapi_ppb_file_io_browser_test.out', + url='ppapi_ppb_file_io.html', + browser_flags=['--unlimited-quota-for-files'], + files=env.ExtractPublishedFiles(nexe)) + +env.AddNodeToTestSuite(node, + ['chrome_browser_tests'], + 'run_ppapi_ppb_file_io_browser_test', + is_broken=env.PPAPIBrowserTesterIsBroken()) diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_file_io/ppapi_ppb_file_io.cc b/ppapi/native_client/tests/ppapi_browser/ppb_file_io/ppapi_ppb_file_io.cc new file mode 100644 index 0000000..d866d98 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_file_io/ppapi_ppb_file_io.cc @@ -0,0 +1,58 @@ +// 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/platform/nacl_check.h" +#include "native_client/tests/ppapi_browser/ppb_file_io/common.h" +#include "native_client/tests/ppapi_test_lib/get_browser_interface.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" + +// Open tests +extern void TestOpenExistingFileLocalPersistent(); +extern void TestOpenExistingFileLocalTemporary(); +extern void TestOpenNonExistingFileLocalPersistent(); +extern void TestOpenNonExistingFileLocalTemporary(); +// Query tests +extern void TestQueryFileLocalPersistent(); +extern void TestQueryFileLocalTemporary(); +// Read tests +extern void TestCompleteReadLocalPersistent(); +extern void TestCompleteReadLocalTemporary(); +extern void TestParallelReadLocalPersistent(); +extern void TestParallelReadLocalTemporary(); +extern void TestPartialFileReadLocalPersistent(); +extern void TestPartialFileReadLocalTemporary(); + +void SetupTests() { + // Open tests + RegisterTest("TestOpenExistingFileLocalPersistent", + TestOpenExistingFileLocalPersistent); + RegisterTest("TestOpenExistingFileLocalTemporary", + TestOpenExistingFileLocalTemporary); + RegisterTest("TestOpenNonExistingFileLocalPersistent", + TestOpenNonExistingFileLocalPersistent); + RegisterTest("TestOpenNonExistingFileLocalTemporary", + TestOpenNonExistingFileLocalTemporary); + // Query tests + RegisterTest("TestQueryFileLocalPersistent", + TestQueryFileLocalPersistent); + RegisterTest("TestQueryFileLocalTemporary", + TestQueryFileLocalTemporary); + // Rest tests + RegisterTest("TestCompleteReadLocalPersistent", + TestCompleteReadLocalPersistent); + RegisterTest("TestCompleteReadLocalTemporary", + TestCompleteReadLocalTemporary); + RegisterTest("TestParallelReadLocalPersistent", + TestParallelReadLocalPersistent); + RegisterTest("TestParallelReadLocalTemporary", + TestParallelReadLocalTemporary); + RegisterTest("TestPartialFileReadLocalPersistent", + TestPartialFileReadLocalPersistent); + RegisterTest("TestPartialFileReadLocalTemporary", + TestPartialFileReadLocalTemporary); +} + +void SetupPluginInterfaces() { + /* No PPP interface to test. */ +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_file_io/ppapi_ppb_file_io.html b/ppapi/native_client/tests/ppapi_browser/ppb_file_io/ppapi_ppb_file_io.html new file mode 100644 index 0000000..77391f6 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_file_io/ppapi_ppb_file_io.html @@ -0,0 +1,29 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + <!-- Copyright 2011 Google Inc. All rights reserved. --> + <head> + <META HTTP-EQUIV="Pragma" CONTENT="no-cache" /> + <META HTTP-EQUIV="Expires" CONTENT="-1" /> + <script type="text/javascript" src="nacltest.js"></script> + <script type="text/javascript" src="ppapi_ppb_file_io.js"></script> + <title>PPAPI PPB_FileIO Test</title> + </head> + <body> + <h1>PPAPI PPB_FileIO Test</h1> + + <embed type="application/x-nacl" id="test_nexe" + name="nacl_module" + src="ppapi_ppb_file_io.nmf" + width="0" height="0" /> + + <script type="text/javascript"> + //<![CDATA[ + var tester = new Tester(); + setupTests(tester, $('test_nexe')); + tester.waitFor($('test_nexe')); + tester.run(); + //]]> + </script> + </body> +</html> diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_file_io/ppapi_ppb_file_io.js b/ppapi/native_client/tests/ppapi_browser/ppb_file_io/ppapi_ppb_file_io.js new file mode 100644 index 0000000..623e86d --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_file_io/ppapi_ppb_file_io.js @@ -0,0 +1,91 @@ +// 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. + +function setupTests(tester, plugin) { + function addTest(testName, responses) { + var expectedMessages = [testName + ':PASSED']; + if (responses != undefined) + expectedMessages = expectedMessages.concat(responses); + tester.addAsyncTest('PPB_FileIO::' + testName, function(test) { + test.expectMessageSequence(plugin, expectedMessages); + plugin.postMessage(testName); + }); + } + var setupCallbacks = [ + 'OpenFileSystemForSetupCallback', + 'OpenFileForSetupCallback', + 'WriteFileForSetupCallback', + 'FlushFileForSetupCallback', + 'TouchFileForSetupCallback']; + addTest('TestOpenExistingFileLocalPersistent', + setupCallbacks.concat(['TestOpenForRead', + 'TestOpenForWrite', + 'TestOpenTruncate', + 'TestOpenForWriteCreateExclusive', + 'TestOpenForWriteCreate', + 'END'])); + addTest('TestOpenExistingFileLocalTemporary', + setupCallbacks.concat(['TestOpenForRead', + 'TestOpenForWrite', + 'TestOpenTruncate', + 'TestOpenForWriteCreateExclusive', + 'TestOpenForWriteCreate', + 'END'])); + addTest('TestOpenNonExistingFileLocalPersistent', + setupCallbacks.concat(['TestOpenForRead', + 'TestOpenForWrite', + 'TestOpenForWriteCreate', + 'DeleteFile', + 'TestOpenForWriteCreateExclusive', + 'END'])); + addTest('TestOpenNonExistingFileLocalTemporary', + setupCallbacks.concat(['TestOpenForRead', + 'TestOpenForWrite', + 'TestOpenForWriteCreate', + 'DeleteFile', + 'TestOpenForWriteCreateExclusive', + 'END'])); + addTest('TestQueryFileLocalPersistent', + setupCallbacks.concat(['OpenFileForTest', + 'TestQuery', + 'TestQueryFileVerify', + 'END'])); + addTest('TestQueryFileLocalTemporary', + setupCallbacks.concat(['OpenFileForTest', + 'TestQuery', + 'TestQueryFileVerify', + 'END'])); + addTest('TestPartialFileReadLocalPersistent', + setupCallbacks.concat(['OpenFileForTest', + 'TestFileRead', + 'ReadCallback:VERIFIED', + 'END'])); + addTest('TestPartialFileReadLocalTemporary', + setupCallbacks.concat(['OpenFileForTest', + 'TestFileRead', + 'ReadCallback:VERIFIED', + 'END'])); + addTest('TestCompleteReadLocalPersistent', + setupCallbacks.concat(['OpenFileForTest', + 'TestFileRead', + 'ReadCallback:VERIFIED', + 'END'])); + addTest('TestCompleteReadLocalTemporary', + setupCallbacks.concat(['OpenFileForTest', + 'TestFileRead', + 'ReadCallback:VERIFIED', + 'END'])); + addTest('TestParallelReadLocalPersistent', + setupCallbacks.concat(['OpenFileForTest', + 'TestParallelRead', + 'ReadCallback:VERIFIED', + 'ReadCallback:VERIFIED', + 'END'])); + addTest('TestParallelReadLocalTemporary', + setupCallbacks.concat(['OpenFileForTest', + 'TestParallelRead', + 'ReadCallback:VERIFIED', + 'ReadCallback:VERIFIED', + 'END'])); +}; diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_file_io/ppapi_ppb_file_io.nmf b/ppapi/native_client/tests/ppapi_browser/ppb_file_io/ppapi_ppb_file_io.nmf new file mode 100644 index 0000000..b19036f --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_file_io/ppapi_ppb_file_io.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": { "url": "ppapi_ppb_file_io_x86-32.nexe" }, + "x86-64": { "url": "ppapi_ppb_file_io_x86-64.nexe" }, + "arm": { "url": "ppapi_ppb_file_io_arm.nexe" } + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_file_io/test_open.cc b/ppapi/native_client/tests/ppapi_browser/ppb_file_io/test_open.cc new file mode 100644 index 0000000..2e2b1ac --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_file_io/test_open.cc @@ -0,0 +1,172 @@ +// 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/third_party/ppapi/c/pp_errors.h" +#include "native_client/src/third_party/ppapi/c/ppb_core.h" +#include "native_client/src/third_party/ppapi/c/ppb_file_io.h" +#include "native_client/src/third_party/ppapi/c/ppb_file_ref.h" +#include "native_client/src/third_party/ppapi/c/ppb_file_system.h" +#include "native_client/src/third_party/ppapi/c/ppb_url_loader.h" +#include "native_client/tests/ppapi_browser/ppb_file_io/common.h" +#include "native_client/tests/ppapi_test_lib/get_browser_interface.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" + +namespace { + +using common::BoundPPAPIFunc; +using common::FileIOTester; +using common::InitFileInfo; +using common::TestCallbackData; +using common::TestSequenceElement; + +class TestOpenExistingFileSequenceElement : public TestSequenceElement { + public: + TestOpenExistingFileSequenceElement(const std::string& name, + int32_t expected_return_value, + int32_t expected_result, int32_t flags) + : TestSequenceElement(name, expected_return_value, expected_result), + flags_(flags) {} + virtual ~TestOpenExistingFileSequenceElement() {} + + private: + virtual BoundPPAPIFunc GetCompletionCallbackInitiatingPPAPIFunction( + TestCallbackData* callback_data) { + return std::tr1::bind(PPBFileIO()->Open, callback_data->existing_file_io, + callback_data->existing_file_ref, flags_, + std::tr1::placeholders::_1); + } + virtual void Setup(TestCallbackData* callback_data) { + // We make sure the file io is closed before each test. + PPBFileIO()->Close(callback_data->existing_file_io); + } + + const int32_t flags_; +}; + +class TestOpenNonExistingFileSequenceElement : public TestSequenceElement { + public: + TestOpenNonExistingFileSequenceElement(const std::string& name, + int32_t expected_return_value, + int32_t expected_result, int32_t flags) + : TestSequenceElement(name, expected_return_value, expected_result), + flags_(flags) {} + virtual ~TestOpenNonExistingFileSequenceElement() {} + + private: + virtual BoundPPAPIFunc GetCompletionCallbackInitiatingPPAPIFunction( + TestCallbackData* callback_data) { + return std::tr1::bind(PPBFileIO()->Open, + callback_data->non_existing_file_io, + callback_data->non_existing_file_ref, flags_, + std::tr1::placeholders::_1); + } + virtual void Setup(TestCallbackData* callback_data) { + // We make sure the file io is closed before each test. + PPBFileIO()->Close(callback_data->non_existing_file_io); + } + + const int32_t flags_; +}; + +class DeleteFile : public TestSequenceElement { + public: + DeleteFile() + : TestSequenceElement("DeleteFile", PP_OK_COMPLETIONPENDING, PP_OK) {} + + private: + virtual BoundPPAPIFunc GetCompletionCallbackInitiatingPPAPIFunction( + TestCallbackData* callback_data) { + return std::tr1::bind(PPBFileRef()->Delete, + callback_data->non_existing_file_ref, + std::tr1::placeholders::_1); + } +}; + +void TestOpenNonExistingFile(PP_FileSystemType system_type) { + PP_FileInfo file_info = { 0 }; + InitFileInfo(system_type, &file_info); + + FileIOTester tester(file_info); + tester.AddSequenceElement( + new TestOpenNonExistingFileSequenceElement("TestOpenForRead", + PP_OK_COMPLETIONPENDING, + PP_ERROR_FILENOTFOUND, + PP_FILEOPENFLAG_READ)); + tester.AddSequenceElement( + new TestOpenNonExistingFileSequenceElement("TestOpenForWrite", + PP_OK_COMPLETIONPENDING, + PP_ERROR_FILENOTFOUND, + PP_FILEOPENFLAG_WRITE)); + tester.AddSequenceElement( + new TestOpenNonExistingFileSequenceElement("TestOpenForWriteCreate", + PP_OK_COMPLETIONPENDING, + PP_OK, + PP_FILEOPENFLAG_CREATE | + PP_FILEOPENFLAG_WRITE)); + tester.AddSequenceElement(new DeleteFile); + tester.AddSequenceElement( + new TestOpenNonExistingFileSequenceElement( + "TestOpenForWriteCreateExclusive", + PP_OK_COMPLETIONPENDING, + PP_OK, + PP_FILEOPENFLAG_WRITE | + PP_FILEOPENFLAG_CREATE | + PP_FILEOPENFLAG_EXCLUSIVE)); + tester.Run(); +} + +void TestOpenExistingFile(PP_FileSystemType system_type) { + PP_FileInfo file_info = { 0 }; + InitFileInfo(system_type, &file_info); + + FileIOTester tester(file_info); + tester.AddSequenceElement( + new TestOpenExistingFileSequenceElement("TestOpenForRead", + PP_OK_COMPLETIONPENDING, PP_OK, + PP_FILEOPENFLAG_READ)); + tester.AddSequenceElement( + new TestOpenExistingFileSequenceElement("TestOpenForWrite", + PP_OK_COMPLETIONPENDING, PP_OK, + PP_FILEOPENFLAG_WRITE)); + tester.AddSequenceElement( + new TestOpenExistingFileSequenceElement("TestOpenTruncate", + PP_ERROR_BADARGUMENT, + PP_ERROR_FAILED, + PP_FILEOPENFLAG_TRUNCATE)); + tester.AddSequenceElement( + new TestOpenExistingFileSequenceElement("TestOpenForWriteCreateExclusive", + PP_OK_COMPLETIONPENDING, + PP_ERROR_FILEEXISTS, + PP_FILEOPENFLAG_WRITE | + PP_FILEOPENFLAG_CREATE | + PP_FILEOPENFLAG_EXCLUSIVE)); + tester.AddSequenceElement( + new TestOpenExistingFileSequenceElement("TestOpenForWriteCreate", + PP_OK_COMPLETIONPENDING, PP_OK, + PP_FILEOPENFLAG_WRITE | + PP_FILEOPENFLAG_CREATE)); + tester.Run(); +} + +} // namespace + +void TestOpenExistingFileLocalPersistent() { + TestOpenExistingFile(PP_FILESYSTEMTYPE_LOCALPERSISTENT); + TEST_PASSED; +} + +void TestOpenExistingFileLocalTemporary() { + TestOpenExistingFile(PP_FILESYSTEMTYPE_LOCALTEMPORARY); + TEST_PASSED; +} + +void TestOpenNonExistingFileLocalPersistent() { + TestOpenNonExistingFile(PP_FILESYSTEMTYPE_LOCALPERSISTENT); + TEST_PASSED; +} + +void TestOpenNonExistingFileLocalTemporary() { + TestOpenNonExistingFile(PP_FILESYSTEMTYPE_LOCALTEMPORARY); + TEST_PASSED; +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_file_io/test_query.cc b/ppapi/native_client/tests/ppapi_browser/ppb_file_io/test_query.cc new file mode 100644 index 0000000..57bc3a4 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_file_io/test_query.cc @@ -0,0 +1,81 @@ +// 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 <string.h> + +#include "native_client/src/third_party/ppapi/c/pp_errors.h" +#include "native_client/src/third_party/ppapi/c/ppb_core.h" +#include "native_client/src/third_party/ppapi/c/ppb_file_io.h" +#include "native_client/src/third_party/ppapi/c/ppb_file_ref.h" +#include "native_client/src/third_party/ppapi/c/ppb_file_system.h" +#include "native_client/tests/ppapi_test_lib/get_browser_interface.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" +#include "native_client/tests/ppapi_browser/ppb_file_io/common.h" + +namespace { + +using common::BoundPPAPIFunc; +using common::FileIOTester; +using common::InitFileInfo; +using common::kTestData; +using common::OpenFileForTest; +using common::TestCallbackData; +using common::TestSequenceElement; + +class TestQuery : public TestSequenceElement { + public: + TestQuery() : TestSequenceElement("TestQuery") {} + + private: + virtual BoundPPAPIFunc GetCompletionCallbackInitiatingPPAPIFunction( + TestCallbackData* callback_data) { + PP_FileInfo* file_info = new PP_FileInfo; + callback_data->data = file_info; + return std::tr1::bind(PPBFileIO()->Query, callback_data->existing_file_io, + file_info, std::tr1::placeholders::_1); + } +}; + +// Verify the results of calling PPB_FileIO:::Query in from a TestQuery object. +class TestQueryFileVerify : public TestSequenceElement { + public: + TestQueryFileVerify() : TestSequenceElement("TestQueryFileVerify") {} + + private: + virtual void Execute(TestCallbackData* callback_data) { + PP_FileInfo* file_info = + reinterpret_cast<PP_FileInfo*>(callback_data->data); + EXPECT(file_info->type == callback_data->file_info.type); + EXPECT(file_info->system_type == callback_data->file_info.system_type); + // TODO(sanga): Fix this with the correct test. + // EXPECT(file_info->last_access_time == + // callback_data->file_info.last_access_time); + EXPECT(file_info->last_modified_time == + callback_data->file_info.last_modified_time); + EXPECT(file_info->size == strlen(kTestData)); + delete file_info; + } +}; + +void TestQueryFile(PP_FileSystemType system_type) { + PP_FileInfo file_info = { 0 }; + InitFileInfo(system_type, &file_info); + FileIOTester tester(file_info); + tester.AddSequenceElement(new OpenFileForTest); + tester.AddSequenceElement(new TestQuery); + tester.AddSequenceElement(new TestQueryFileVerify); + tester.Run(); +} + +} // namespace + +void TestQueryFileLocalPersistent() { + TestQueryFile(PP_FILESYSTEMTYPE_LOCALPERSISTENT); + TEST_PASSED; +} + +void TestQueryFileLocalTemporary() { + TestQueryFile(PP_FILESYSTEMTYPE_LOCALTEMPORARY); + TEST_PASSED; +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_file_io/test_read.cc b/ppapi/native_client/tests/ppapi_browser/ppb_file_io/test_read.cc new file mode 100644 index 0000000..c036b35 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_file_io/test_read.cc @@ -0,0 +1,189 @@ +// 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 <string.h> + +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/src/third_party/ppapi/c/pp_errors.h" +#include "native_client/src/third_party/ppapi/c/ppb_file_io.h" +#include "native_client/tests/ppapi_test_lib/get_browser_interface.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" +#include "native_client/tests/ppapi_browser/ppb_file_io/common.h" + +namespace { + +using common::FileIOTester; +using common::InitFileInfo; +using common::kTestData; +using common::OpenFileForTest; +using common::TestCallbackData; +using common::TestSequenceElement; + +struct TestReadData { + TestReadData(PP_Resource file_io, int64_t offset_bytes, int32_t bytes_to_read) + : file_io(file_io), buffer(new char[bytes_to_read]), + offset(offset_bytes), bytes_to_read(bytes_to_read), bytes_read(0) { } + ~TestReadData() { + delete[] buffer; + } + + const PP_Resource file_io; + char* const buffer; + const int64_t offset; + const int32_t bytes_to_read; + int32_t bytes_read; +}; + +// Completion callback function called from the read operation. If the read +// operation is not completed, a successive read operation will be invoked. +void ReadCallback(void* data, int32_t bytes_read) { + EXPECT(bytes_read >= 0); + + TestReadData* read_data = reinterpret_cast<TestReadData*>(data); + read_data->bytes_read += bytes_read; + + if (read_data->bytes_read == read_data->bytes_to_read || + bytes_read == 0) { // no more bytes to available to read + // Verify the data + EXPECT(strncmp(kTestData + read_data->offset, read_data->buffer, + read_data->bytes_read) == 0); + PostTestMessage(__FUNCTION__, "VERIFIED"); // Test for this in browser. + delete read_data; + } else { + int64_t offset = read_data->offset + read_data->bytes_read; + char* buffer = read_data->buffer + read_data->bytes_read; + int32_t bytes_to_read = + read_data->bytes_to_read - read_data->bytes_read; + PPBFileIO()->Read(read_data->file_io, offset, buffer, bytes_to_read, + PP_MakeCompletionCallback(ReadCallback, read_data)); + } +} + +// TestParallelRead performs two read operations, one from the beginning of the +// file, and one from the offset. Both operations are of the same size. +class TestParallelRead : public TestSequenceElement { + public: + TestParallelRead(int64_t offset, int32_t bytes_to_read) + : TestSequenceElement("TestParallelRead", PP_OK_COMPLETIONPENDING, PP_OK), + offset_(offset), bytes_to_read_(bytes_to_read) {} + + private: + virtual void Setup(TestCallbackData* callback_data) { + TestReadData* read_data = new TestReadData(callback_data->existing_file_io, + 0, // read from beginning + bytes_to_read_); + int32_t pp_error = PPBFileIO()->Read(read_data->file_io, read_data->offset, + read_data->buffer, + read_data->bytes_to_read, + PP_MakeCompletionCallback(ReadCallback, + read_data)); + EXPECT(pp_error == PP_OK_COMPLETIONPENDING); + + read_data = new TestReadData(callback_data->existing_file_io, offset_, + bytes_to_read_); + pp_error = PPBFileIO()->Read(read_data->file_io, read_data->offset, + read_data->buffer, + read_data->bytes_to_read, + PP_MakeCompletionCallback(ReadCallback, + read_data)); + EXPECT(pp_error == PP_OK_COMPLETIONPENDING); + } + + const int32_t offset_; + const int32_t bytes_to_read_; +}; + +class TestFileRead : public TestSequenceElement { + public: + TestFileRead(int64_t offset, int32_t bytes_to_read) + : TestSequenceElement("TestFileRead", PP_OK_COMPLETIONPENDING, PP_OK), + offset_(offset), bytes_to_read_(bytes_to_read) {} + + private: + void Setup(TestCallbackData* callback_data) { + TestReadData* read_data = new TestReadData(callback_data->existing_file_io, + offset_, bytes_to_read_); + int32_t pp_error = PPBFileIO()->Read(read_data->file_io, read_data->offset, + read_data->buffer, + read_data->bytes_to_read, + PP_MakeCompletionCallback(ReadCallback, + read_data)); + EXPECT(pp_error == PP_OK_COMPLETIONPENDING); + } + + const int64_t offset_; + const int32_t bytes_to_read_; +}; + +// Test the partial read of a file +void TestPartialFileRead(PP_FileSystemType system_type) { + PP_FileInfo file_info = { 0 }; + InitFileInfo(system_type, &file_info); + + const int64_t offset = 1; // some non-zero offset + const int32_t bytes_to_read = strlen(kTestData) / 2; + + FileIOTester tester(file_info); + tester.AddSequenceElement(new OpenFileForTest); + tester.AddSequenceElement(new TestFileRead(offset, bytes_to_read)); + tester.Run(); +} + +// Test complete read of a file in one operation. +void TestCompleteReadFile(PP_FileSystemType system_type) { + PP_FileInfo file_info = { 0 }; + InitFileInfo(system_type, &file_info); + + FileIOTester tester(file_info); + tester.AddSequenceElement(new OpenFileForTest); + tester.AddSequenceElement(new TestFileRead(0, // start at beginning + strlen(kTestData))); + tester.Run(); +} + +void TestParallelReadFile(PP_FileSystemType system_type) { + PP_FileInfo file_info = { 0 }; + InitFileInfo(system_type, &file_info); + + const int64_t offset = strlen(kTestData) / 2; + const int32_t bytes_to_read = strlen(kTestData) / 3; + + FileIOTester tester(file_info); + tester.AddSequenceElement(new OpenFileForTest); + tester.AddSequenceElement(new TestParallelRead(offset, bytes_to_read)); + tester.Run(); +} + +} // namespace + +void TestPartialFileReadLocalPersistent() { + TestPartialFileRead(PP_FILESYSTEMTYPE_LOCALPERSISTENT); + TEST_PASSED; +} + +void TestPartialFileReadLocalTemporary() { + TestPartialFileRead(PP_FILESYSTEMTYPE_LOCALTEMPORARY); + TEST_PASSED; +} + +void TestCompleteReadLocalPersistent() { + TestCompleteReadFile(PP_FILESYSTEMTYPE_LOCALPERSISTENT); + TEST_PASSED; +} + +void TestCompleteReadLocalTemporary() { + TestCompleteReadFile(PP_FILESYSTEMTYPE_LOCALTEMPORARY); + TEST_PASSED; +} + +// Test multiple reads of a file using multiple callbacks and different offsets. +void TestParallelReadLocalPersistent() { + TestParallelReadFile(PP_FILESYSTEMTYPE_LOCALPERSISTENT); + TEST_PASSED; +} + +void TestParallelReadLocalTemporary() { + TestParallelReadFile(PP_FILESYSTEMTYPE_LOCALTEMPORARY); + TEST_PASSED; +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_file_io/test_sequence_element.cc b/ppapi/native_client/tests/ppapi_browser/ppb_file_io/test_sequence_element.cc new file mode 100644 index 0000000..2e47020 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_file_io/test_sequence_element.cc @@ -0,0 +1,104 @@ +// 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/tests/ppapi_browser/ppb_file_io/test_sequence_element.h" + +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/third_party/ppapi/c/ppb_core.h" +#include "native_client/tests/ppapi_test_lib/get_browser_interface.h" + +namespace common { + +TestSequenceElement::~TestSequenceElement() {} + +// TestSequenceElementForwardingCallback is the completion callback which +// connects one test sequence element to another. +void TestSequenceElement::TestSequenceElementForwardingCallback( + void* data, + int32_t result) { + TestCallbackData* callback_data = reinterpret_cast<TestCallbackData*>(data); + // If result is greater than 0, it is a result of a read/write. In that case + // we ignore the result since it represents the number of bytes read/written, + // which is not guaranteed to be a specific size. + if (result <= 0) + EXPECT(result == callback_data->expected_result); + nacl::scoped_ptr<TestSequenceElement> sequence_element( + callback_data->test_sequence.front()); + sequence_element->Run(callback_data, result); +} + +// TODO(sanga): Move this to file_io_tester.h +void TestSequenceElement::CleanupResources( + TestCallbackData* callback_data) { // sink + PPBCore()->ReleaseResource(callback_data->existing_file_io); + PPBCore()->ReleaseResource(callback_data->existing_file_ref); + PPBCore()->ReleaseResource(callback_data->non_existing_file_io); + PPBCore()->ReleaseResource(callback_data->non_existing_file_ref); + PPBCore()->ReleaseResource(callback_data->file_system); + delete callback_data; +} + +void TestSequenceElement::Run(TestCallbackData* callback_data, int32_t result) { + callback_data->expected_return_value = expected_return_value_; + callback_data->expected_result = expected_result_; + Setup(callback_data); + Execute(callback_data); + // Invoke a ppapi function that kicks off another callback. + callback_data->test_sequence.pop_front(); // pop self off the dequeue + Next(callback_data); +} + +void TestSequenceElement::TestSequenceTerminatingCallback(void* data, + int32_t result) { + TestCallbackData* callback_data = reinterpret_cast<TestCallbackData*>(data); + // If result is greater than 0, it is a result of a read/write. In that case + // we ignore the result since it represents the number of bytes read/written, + // which is not guaranteed to be a specific size. + if (result <= 0) + EXPECT(result == callback_data->expected_result); + CleanupResources(callback_data); +} + +namespace { + +int32_t CallbackInvokingNoOpFunction(int32_t delay_in_milliseconds, + PP_CompletionCallback callback) { + PPBCore()->CallOnMainThread(delay_in_milliseconds, callback, PP_OK); + return PP_OK_COMPLETIONPENDING; +} + +} // namespace + +BoundPPAPIFunc +TestSequenceElement::GetCompletionCallbackInitiatingPPAPIFunction( + TestCallbackData* /*callback_data*/) { + return std::tr1::bind(CallbackInvokingNoOpFunction, 0, + std::tr1::placeholders::_1); +} + +void TestSequenceElement::Next(TestCallbackData* callback_data) { + PP_CompletionCallback_Func callback_func = NULL; + std::string callback_name = "END"; + if (!callback_data->test_sequence.empty()) { + callback_func = TestSequenceElementForwardingCallback; + TestSequenceElement* next_element = callback_data->test_sequence.front(); + callback_name = next_element->name(); + } else { + callback_func = TestSequenceTerminatingCallback; + } + PP_CompletionCallback completion_callback = MakeTestableCompletionCallback( + callback_name.c_str(), callback_func, callback_data); + BoundPPAPIFunc ppapi_func = + GetCompletionCallbackInitiatingPPAPIFunction(callback_data); + int32_t pp_error = ppapi_func(completion_callback); + EXPECT(pp_error == callback_data->expected_return_value); + if (pp_error != PP_OK_COMPLETIONPENDING) { + // We need to invoke to the next callback. + PPBCore()->CallOnMainThread(0, // no delay + completion_callback, + callback_data->expected_result); + } +} + +} // namespace common diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_file_io/test_sequence_element.h b/ppapi/native_client/tests/ppapi_browser/ppb_file_io/test_sequence_element.h new file mode 100644 index 0000000..10b60fa --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_file_io/test_sequence_element.h @@ -0,0 +1,131 @@ +// 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. +#ifndef NATIVE_CLIENT_TESTS_PPAPI_BROWSER_PPB_FILE_IO_TEST_SEQUENCE_ELEMENT_H_ +#define NATIVE_CLIENT_TESTS_PPAPI_BROWSER_PPB_FILE_IO_TEST_SEQUENCE_ELEMENT_H_ + +#include <deque> +#include <string> +#include <tr1/functional> + +#include "native_client/src/include/nacl_base.h" +#include "native_client/src/third_party/ppapi/c/pp_errors.h" +#include "native_client/src/third_party/ppapi/c/pp_file_info.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" + +namespace common { + +class TestSequenceElement; + +// TestCallbackData is used to pass data from on test sequence element to +// another, e.g. file io, file ref, etc. +struct TestCallbackData { + TestCallbackData(PP_Resource system, + PP_FileInfo info, + std::deque<TestSequenceElement*> sequence) + : file_system(system), file_info(info), + existing_file_io(kInvalidResource), existing_file_ref(kInvalidResource), + non_existing_file_io(kInvalidResource), + non_existing_file_ref(kInvalidResource), expected_result(PP_OK), + expected_return_value(PP_OK_COMPLETIONPENDING), data(NULL), + test_sequence(sequence) {} + + const PP_Resource file_system; + const PP_FileInfo file_info; + PP_Resource existing_file_io; + PP_Resource existing_file_ref; + PP_Resource non_existing_file_io; + PP_Resource non_existing_file_ref; + // The following known properties of the file assigned to the file before + // testing. + int32_t expected_result; // The expected result of a callback operation. + int32_t expected_return_value; + void* data; // Used to attach contextual data + // Array of test functions that themselve can invoke functions which trigger a + // callback. + std::deque<TestSequenceElement*> test_sequence; +}; + +// OpenFileForTest is an element in a test sequence used to open the existing +typedef std::tr1::function<int32_t (PP_CompletionCallback)> BoundPPAPIFunc; + +// TestSequenceElement is a specific section of a sequence of tests. +// Each element may or may not have side effects that effect the subsequent test +// sequence elements (e.g. opening or closing a file). +// Example: +// class ConcreteTestElement : public TestSequenceElement { +// private: +// virtual BoundPPAPIFunc +// GetCompletionCallbackInitiatingPPAPIFunction( +// TestCallbackData* callback_data) { +// return std::tr1::bind(PPBFileRef()->Delete, +// callback_data->existing_file_ref, +// std::tr1::placeholder::_1); +// } +// +// void TestFoo() { +// PP_FileInfo file_info; +// InitFileInfo(PP_FILESYSTEMTYPE_LOCALTEMPORARY, &file_info); +// FileIOTester tester(file_info); +// tester.AddSequenceElement(new ConcreteTestElement); +// tester.Run(); +// } +class TestSequenceElement { + public: + explicit TestSequenceElement(const std::string& name) + : name_(name), expected_return_value_(PP_OK_COMPLETIONPENDING), + expected_result_(PP_OK) {} + TestSequenceElement(const std::string& name, int32_t expected_return_value, + int32_t expected_result) + : name_(name), expected_return_value_(expected_return_value), + expected_result_(expected_result) {} + virtual ~TestSequenceElement(); + + // TestSequenceElementForwardingCallback is the callback that is called from + // the previous sequence element's invocation of a ppapi function which calls + // a completion callback. + static void TestSequenceElementForwardingCallback(void* data, int32_t result); + static void CleanupResources(TestCallbackData* callback_data); + + // Run executes the element's section of the test sequence. + // |callback_data| is a pointer to data being passed through each element. + // |result| is the result of the ppapi operation invoked by previous element + // in the test sequence. + void Run(TestCallbackData* callback_data, + int32_t result); + const char* name() { return name_.c_str(); } + + private: + TestSequenceElement(); // Disable default ctor + + static void TestSequenceTerminatingCallback(void* data, int32_t result); + + // Returns a PPAPI function that initiates a completion callback. This is + // produced by taking a PPAPI function that takes a completion callback as the + // last argument and possibly binding every other parameter with values from + // the given test data (e.g.): + // return std::tr1::bind(PPB_FileRef()->Delete, + // callback_data->existing_file_ref, + // std::tr1::_1) + // Subclasses define this function to chain the test sequence element with + // ppapi functions. + virtual BoundPPAPIFunc GetCompletionCallbackInitiatingPPAPIFunction( + TestCallbackData* callback_data); + // Set up. Can be a no-op if not defined by subcass. + virtual void Setup(TestCallbackData* callback_data) {} + // Implemented by subclasses to verify results of previously test sequence + // elements or modify known states for subsequent test elements. + virtual void Execute(TestCallbackData* callback_data) {} + + void Next(TestCallbackData* callback_data); + + const std::string name_; + const int32_t expected_return_value_; + const int32_t expected_result_; + + DISALLOW_COPY_AND_ASSIGN(TestSequenceElement); +}; + +} // namespace common + +#endif // NATIVE_CLIENT_TESTS_PPAPI_BROWSER_PPB_FILE_IO_TEST_SEQUENCE_ELEMENT_H_ diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_file_system/build.scons b/ppapi/native_client/tests/ppapi_browser/ppb_file_system/build.scons new file mode 100644 index 0000000..27e2b52 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_file_system/build.scons @@ -0,0 +1,26 @@ +# -*- python -*- +# Copyright 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. + +# A way to build the nexe as a trusted plugin to validate directly +# against Chrome on Linux using +# --register-pepper-plugins="/path/to/libppapi_ppb_file_system.so;application/x-nacl" +# http://localhost:5103/scons-out/nacl-x86-../staging/ppapi_ppb_file_system.html + +Import('env') + +if env.Bit('linux'): + env['COMPONENT_STATIC'] = False # Build a .so, not a .a + env.Append(CFLAGS=['-std=c99']) + + sources = ['ppapi_ppb_file_system.cc'] + + libs = ['imc', + 'gio', + 'pthread' ] + + ppapi_geturl = env.ComponentLibrary('ppapi_ppb_file_system', + sources, + EXTRA_LIBS=libs, + no_import_lib=True) diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_file_system/nacl.scons b/ppapi/native_client/tests/ppapi_browser/ppb_file_system/nacl.scons new file mode 100644 index 0000000..9a04c5a --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_file_system/nacl.scons @@ -0,0 +1,36 @@ +# -*- python -*- +# 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. +# +# This test uses ppapi_test_lib. + +Import('env') + +env.Prepend(CPPDEFINES=['XP_UNIX']) + +nexe = 'ppapi_ppb_file_system_%s' % env.get('TARGET_FULLARCH') +env.Alias('ppapi_ppb_file_system${PROGSUFFIX}', + ['$STAGING_DIR/%s${PROGSUFFIX}' % nexe]) + +env.ComponentProgram(nexe, + ['ppapi_ppb_file_system.cc'], + EXTRA_LIBS=['${PPAPI_LIBS}', + 'ppapi_test_lib', + 'platform', + 'pthread', + 'gio']) + +env.Publish(nexe, 'run', + ['ppapi_ppb_file_system.html', + 'ppapi_ppb_file_system.nmf', + 'ppapi_ppb_file_system.js']) + +node = env.PPAPIBrowserTester('ppapi_ppb_file_system_browser_test.out', + url='ppapi_ppb_file_system.html', + files=env.ExtractPublishedFiles(nexe)) + +env.AddNodeToTestSuite(node, + ['chrome_browser_tests'], + 'run_ppapi_ppb_file_system_browser_test', + is_broken=env.PPAPIBrowserTesterIsBroken()) diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_file_system/ppapi_ppb_file_system.cc b/ppapi/native_client/tests/ppapi_browser/ppb_file_system/ppapi_ppb_file_system.cc new file mode 100644 index 0000000..d5ec60f --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_file_system/ppapi_ppb_file_system.cc @@ -0,0 +1,192 @@ +// 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/tests/ppapi_test_lib/get_browser_interface.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" +#include "native_client/src/shared/platform/nacl_check.h" +#include "ppapi/c/ppb_core.h" +#include "ppapi/c/ppb_file_system.h" +#include "ppapi/c/ppb_url_request_info.h" +#include "ppapi/c/pp_errors.h" + +namespace { + +void OpenCallback(void* /*data*/, int32_t /*result*/) { +} + +const PP_FileSystemType kFileSystemTypes[] = { + PP_FILESYSTEMTYPE_EXTERNAL, + PP_FILESYSTEMTYPE_LOCALPERSISTENT, + PP_FILESYSTEMTYPE_LOCALTEMPORARY +}; + +const size_t kNumFileSystemTypes = + sizeof(kFileSystemTypes) / sizeof(kFileSystemTypes[0]); + +void TestCreate() { + PP_Resource file_system = kInvalidResource; + const PPB_FileSystem* ppb_file_system = PPBFileSystem(); + // Test to see if PPB_FileSystem::Create returns PP_Resource value of 0 + // if the instance parameter is invalid. + file_system = ppb_file_system->Create(kInvalidInstance, + PP_FILESYSTEMTYPE_EXTERNAL); + EXPECT(file_system == kInvalidResource); + file_system = ppb_file_system->Create(kInvalidInstance, + PP_FILESYSTEMTYPE_LOCALPERSISTENT); + EXPECT(file_system == kInvalidResource); + file_system = ppb_file_system->Create(kInvalidInstance, + PP_FILESYSTEMTYPE_LOCALTEMPORARY); + EXPECT(file_system == kInvalidResource); + + // Test for failure when an invalid file system type is requested. + file_system = ppb_file_system->Create(pp_instance(), + PP_FILESYSTEMTYPE_INVALID); + EXPECT(file_system == kInvalidResource); + + // Test to see if PPB_FileSystem::Create returns a valid PP_Resource + // value when given a valid PP_Instance value parameter. Test for all + // three file system types PPB_FileSystem supports. + for (size_t i = 0; i < kNumFileSystemTypes; ++i) { + file_system = ppb_file_system->Create(pp_instance(), kFileSystemTypes[i]); + EXPECT(file_system != kInvalidResource); + PPBCore()->ReleaseResource(file_system); + } + TEST_PASSED; +} + +void TestIsFileSystem() { + const PPB_Core* ppb_core = PPBCore(); + const PPB_FileSystem* ppb_file_system = PPBFileSystem(); + PP_Resource file_system = kInvalidResource; + PP_Bool is_file_system = PP_FALSE; + + // Test fail for invalid resource. + EXPECT(ppb_file_system->IsFileSystem(kInvalidResource) != PP_TRUE); + + // Test pass for the different valid system types, and test fail against a + // resource that has been released. + for (size_t i = 0; i < kNumFileSystemTypes; ++i) { + file_system = ppb_file_system->Create(pp_instance(), kFileSystemTypes[i]); + CHECK(file_system != kInvalidResource); + + is_file_system = ppb_file_system->IsFileSystem(file_system); + ppb_core->ReleaseResource(file_system); + + EXPECT(is_file_system == PP_TRUE); + + is_file_system = ppb_file_system->IsFileSystem(file_system); + EXPECT(is_file_system == PP_FALSE); + } + + // Test fail against a non-filesystem resource. + PP_Resource url_request_info = PPBURLRequestInfo()->Create(pp_instance()); + CHECK(url_request_info != kInvalidResource); + is_file_system = ppb_file_system->IsFileSystem(url_request_info); + ppb_core->ReleaseResource(url_request_info); + EXPECT(is_file_system == PP_FALSE); + + TEST_PASSED; +} + +void TestOpen() { + const PPB_Core* ppb_core = PPBCore(); + const PPB_FileSystem* ppb_file_system = PPBFileSystem(); + PP_Resource file_system = kInvalidResource; + PP_CompletionCallback nop_callback = + MakeTestableCompletionCallback("NopCallback", OpenCallback); + PP_CompletionCallback open_callback = + MakeTestableCompletionCallback("OpenCallback", OpenCallback, NULL); + int32_t pp_error = PP_ERROR_FAILED; + int64_t kSize = 1024; // Dummy value. + + // Test to make sure opening an invalid file system fails. + pp_error = ppb_file_system->Open(kInvalidResource, kSize, nop_callback); + EXPECT(pp_error == PP_ERROR_BADRESOURCE); + + // Test to make sure external file system is not supported. + // TODO(sanga): Once Chrome supports external file systems, change this test + // to reflect the change. + file_system = ppb_file_system->Create(pp_instance(), + PP_FILESYSTEMTYPE_EXTERNAL); + pp_error = ppb_file_system->Open(file_system, kSize, nop_callback); + ppb_core->ReleaseResource(file_system); + EXPECT(pp_error == PP_ERROR_FAILED); + + // Test local temporary and local persistant file systems. + for (size_t i = 1; i < kNumFileSystemTypes; ++i) { +#ifdef __native_client__ + // Test fail for blocking open. + // + // Only conduct this test with nexe. Trusted ppapi plugin does not work + // with synchronous Open call. + // See http://code.google.com/p/chromium/issues/detail?id=78449 + file_system = ppb_file_system->Create(pp_instance(), kFileSystemTypes[i]); + pp_error = ppb_file_system->Open(file_system, kSize, + PP_BlockUntilComplete()); + ppb_core->ReleaseResource(file_system); + EXPECT(pp_error == PP_ERROR_BADARGUMENT); +#endif + + // Test success for asynchronous open. + file_system = ppb_file_system->Create(pp_instance(), kFileSystemTypes[i]); + pp_error = ppb_file_system->Open(file_system, kSize, open_callback); + ppb_core->ReleaseResource(file_system); + EXPECT(pp_error == PP_OK_COMPLETIONPENDING); + open_callback = + MakeTestableCompletionCallback("OpenCallback", OpenCallback); + + // Test fail for multiple opens. + file_system = ppb_file_system->Create(pp_instance(), kFileSystemTypes[i]); + pp_error = ppb_file_system->Open(file_system, kSize, open_callback); + CHECK(pp_error == PP_OK_COMPLETIONPENDING); // Previously tested. + pp_error = ppb_file_system->Open(file_system, kSize, nop_callback); + ppb_core->ReleaseResource(file_system); + // TODO(polina, sanga): take out PP_ERROR_FAILED when chrome is fixed. + EXPECT(pp_error == PP_ERROR_FAILED || pp_error == PP_ERROR_INPROGRESS); + } + TEST_PASSED; +} + +void TestGetType() { + const PPB_Core* ppb_core = PPBCore(); + const PPB_FileSystem* ppb_file_system = PPBFileSystem(); + PP_Resource file_system = kInvalidResource; + PP_FileSystemType type = PP_FILESYSTEMTYPE_INVALID; + + // Test for invalid resource. + EXPECT(PP_FILESYSTEMTYPE_INVALID == ppb_file_system->GetType(0)); + + // Test pass for the different valid system types. + for (size_t i = 0; i < kNumFileSystemTypes; ++i) { + file_system = ppb_file_system->Create(pp_instance(), kFileSystemTypes[i]); + CHECK(file_system != kInvalidResource); + + type = ppb_file_system->GetType(file_system); + ppb_core->ReleaseResource(file_system); + + EXPECT(type == kFileSystemTypes[i]); + } + + // Test fail against a non-filesystem resource. + PP_Resource url_request_info = PPBURLRequestInfo()->Create(pp_instance()); + CHECK(url_request_info != kInvalidResource); + type = ppb_file_system->GetType(url_request_info); + ppb_core->ReleaseResource(url_request_info); + EXPECT(type == PP_FILESYSTEMTYPE_INVALID); + + TEST_PASSED; +} + +} // namespace + +void SetupTests() { + RegisterTest("TestCreate", TestCreate); + RegisterTest("TestIsFileSystem", TestIsFileSystem); + RegisterTest("TestOpen", TestOpen); + RegisterTest("TestGetType", TestGetType); +} + +void SetupPluginInterfaces() { + /* No PPP interface to test. */ +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_file_system/ppapi_ppb_file_system.html b/ppapi/native_client/tests/ppapi_browser/ppb_file_system/ppapi_ppb_file_system.html new file mode 100644 index 0000000..6fd53b7 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_file_system/ppapi_ppb_file_system.html @@ -0,0 +1,29 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + <!-- Copyright 2011 Google Inc. All rights reserved. --> + <head> + <META HTTP-EQUIV="Pragma" CONTENT="no-cache" /> + <META HTTP-EQUIV="Expires" CONTENT="-1" /> + <script type="text/javascript" src="nacltest.js"></script> + <script type="text/javascript" src="ppapi_ppb_file_system.js"></script> + <title>PPAPI PPB_FileSytem_Dev Test</title> + </head> + <body> + <h1>PPAPI PPB_FileSystem_Dev Test</h1> + + <embed type="application/x-nacl" id="test_nexe" + name="nacl_module" + src="ppapi_ppb_file_system.nmf" + width="0" height="0" /> + + <script type="text/javascript"> + //<![CDATA[ + var tester = new Tester(); + setupTests(tester, $('test_nexe')); + tester.waitFor($('test_nexe')); + tester.run(); + //]]> + </script> + </body> +</html> diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_file_system/ppapi_ppb_file_system.js b/ppapi/native_client/tests/ppapi_browser/ppb_file_system/ppapi_ppb_file_system.js new file mode 100644 index 0000000..0c3d225 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_file_system/ppapi_ppb_file_system.js @@ -0,0 +1,53 @@ +// 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. + +function setupTests(tester, plugin) { + tester.addAsyncTest('TestCreate', function(status) { + var messageListener = status.wrap(function(message) { + status.log('Received message: ' + message.data); + plugin.removeEventListener('message', messageListener, false); + status.assertEqual(message.data, 'TestCreate:PASSED'); + status.pass(); + }); + plugin.addEventListener("message", messageListener, false); + plugin.postMessage("TestCreate"); + }); + tester.addAsyncTest('TestIsFileSystem', function(status) { + var messageListener = status.wrap(function(message) { + status.log('Received message: ' + message.data); + plugin.removeEventListener('message', messageListener, false); + status.assertEqual(message.data, 'TestIsFileSystem:PASSED'); + status.pass(); + }); + plugin.addEventListener("message", messageListener, false); + plugin.postMessage("TestIsFileSystem"); + }); + tester.addAsyncTest('TestGetType', function(status) { + var messageListener = status.wrap(function(message) { + status.log('Received message: ' + message.data); + plugin.removeEventListener('message', messageListener, false); + status.assertEqual(message.data, 'TestGetType:PASSED'); + status.pass(); + }); + plugin.addEventListener("message", messageListener, false); + plugin.postMessage("TestGetType"); + }); + tester.addAsyncTest('TestOpen', function(status) { + var gotPassed = false; + var messageListener = status.wrap(function(message) { + status.log('Received message: ' + message.data); + plugin.removeEventListener('message', messageListener, false); + if (!gotPassed) { + status.assertEqual(message.data, 'TestOpen:PASSED'); + gotPassed = true; + plugin.addEventListener("message", messageListener, false); + } else { + status.assertEqual(message.data, 'OpenCallback'); + status.pass(); + } + }); + plugin.addEventListener("message", messageListener, false); + plugin.postMessage("TestOpen"); + }); +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_file_system/ppapi_ppb_file_system.nmf b/ppapi/native_client/tests/ppapi_browser/ppb_file_system/ppapi_ppb_file_system.nmf new file mode 100644 index 0000000..699ee05 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_file_system/ppapi_ppb_file_system.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": { "url": "ppapi_ppb_file_system_x86-32.nexe" }, + "x86-64": { "url": "ppapi_ppb_file_system_x86-64.nexe" }, + "arm": { "url": "ppapi_ppb_file_system_arm.nexe" } + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_graphics2d/nacl.scons b/ppapi/native_client/tests/ppapi_browser/ppb_graphics2d/nacl.scons new file mode 100644 index 0000000..82e7aa8 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_graphics2d/nacl.scons @@ -0,0 +1,43 @@ +# -*- python -*- +# 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. +# +# This test uses ppapi_test_lib. + +Import('env') + +env.Prepend(CPPDEFINES=['XP_UNIX']) + +nexe = 'ppapi_ppb_graphics2d_${TARGET_FULLARCH}' +env.Alias('ppapi_ppb_graphics2d${PROGSUFFIX}', + ['$STAGING_DIR/%s${PROGSUFFIX}' % nexe]) + +ppapi_ppb_graphics2d_nexe = env.ComponentProgram( + nexe, + [ 'ppapi_ppb_graphics2d.cc' ], + EXTRA_LIBS=['${PPAPI_LIBS}', + 'ppapi_test_lib', + 'platform', # for CHECK + 'pthread', + 'gio', + ]) + +dest_copy = env.Publish(nexe, 'run', + [ 'ppapi_ppb_graphics2d.html', + 'ppapi_ppb_graphics2d.nmf', + env.File('${SCONSTRUCT_DIR}/tools/browser_tester/' + 'browserdata/nacltest.js') ] + ) + +node = env.PPAPIBrowserTester('ppapi_ppb_graphics2d_browser_test.out', + url='ppapi_ppb_graphics2d.html', + files=[ ppapi_ppb_graphics2d_nexe, + env.File('ppapi_ppb_graphics2d.nmf'), + env.File('ppapi_ppb_graphics2d.html')], + browser_flags=['--enable-pepper-testing']) + +env.AddNodeToTestSuite(node, + ['chrome_browser_tests'], + 'run_ppapi_ppb_graphics2d_browser_test', + is_broken=env.PPAPIBrowserTesterIsBroken()) diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_graphics2d/ppapi_ppb_graphics2d.cc b/ppapi/native_client/tests/ppapi_browser/ppb_graphics2d/ppapi_ppb_graphics2d.cc new file mode 100644 index 0000000..ec86b13 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_graphics2d/ppapi_ppb_graphics2d.cc @@ -0,0 +1,553 @@ +// 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. +// +// Test cases for PPB_Graphics2D functions. +// As most of them return void, the test automatically confirms that +// there is no crash while requiring a visual inspection of the painted output. + +#include <string.h> + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/tests/ppapi_test_lib/get_browser_interface.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" +#include "ppapi/c/dev/ppb_testing_dev.h" +#include "ppapi/c/pp_bool.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_point.h" +#include "ppapi/c/pp_rect.h" +#include "ppapi/c/pp_size.h" +#include "ppapi/c/ppb_core.h" +#include "ppapi/c/ppb_graphics_2d.h" +#include "ppapi/c/ppb_image_data.h" +#include "ppapi/c/ppb_instance.h" +#include "ppapi/c/ppb_url_loader.h" + +namespace { + +const PP_Bool kAlwaysOpaque = PP_TRUE; +const PP_Bool kNotAlwaysOpaque = PP_FALSE; +const PP_Size kNegativeWidth = PP_MakeSize(-1, 1); +const PP_Size kNegativeHeight = PP_MakeSize(1, -1); +const PP_Size kZeroPixels = PP_MakeSize(0, 0); +const PP_Size kOnePixel = PP_MakeSize(1, 1); +const PP_Size k90x90 = PP_MakeSize(90, 90); +const PP_Size k60x60 = PP_MakeSize(60, 60); +const PP_Size k30x30 = PP_MakeSize(30, 30); +const PP_Size k2500x2500 = PP_MakeSize(2500, 2500); +const PP_Size k100000x100000 = PP_MakeSize(100000, 100000); +const PP_Point kOrigin = PP_MakePoint(0, 0); +const PP_Rect kBadRect = { PP_MakePoint(-1, -1), PP_MakeSize(-1, -1) }; +const PP_Rect* kEntireImage = NULL; +const PP_Bool kInitToZero = PP_TRUE; + +// TODO(polina, nfullagar): allow specification of non-premultipled colors +// and provide alpha premultiplcation in FormatColor(). This will be required +// when future PPAPI pixel formats are extended to include non-premultipled +// or ignored alpha. + +struct ColorPremul { uint32_t A, R, G, B; }; // Use premultipled Alpha. +const ColorPremul kSheerRed = { 0x88, 0x88, 0x00, 0x00 }; +const ColorPremul kSheerBlue = { 0x88, 0x00, 0x00, 0x88 }; +const ColorPremul kSheerGray = { 0x77, 0x55, 0x55, 0x55 }; +const ColorPremul kOpaqueGreen = { 0xFF, 0x00, 0xFF, 0x00 }; +const ColorPremul kOpaqueBlack = { 0xFF, 0x00, 0x00, 0x00 }; +const ColorPremul kOpaqueWhite = { 0xFF, 0xFF, 0xFF, 0xFF }; +const ColorPremul kOpaqueYellow = { 0xFF, 0xFF, 0xFF, 0x00 }; +const int kBytesPerPixel = sizeof(uint32_t); // 4 bytes for BGRA or RGBA. + +// Assumes premultipled Alpha. +uint32_t FormatColor(PP_ImageDataFormat format, ColorPremul color) { + if (format == PP_IMAGEDATAFORMAT_BGRA_PREMUL) + return (color.A << 24) | (color.R << 16) | (color.G << 8) | (color.B); + else if (format == PP_IMAGEDATAFORMAT_RGBA_PREMUL) + return (color.A << 24) | (color.B << 16) | (color.G << 8) | (color.R); + else + NACL_NOTREACHED(); +} + +// Make graphics2d contexts for each test the same size, so we can layer +// the images without invalidating the previous ones. +PP_Resource CreateGraphics2D_90x90() { + PP_Resource graphics2d = PPBGraphics2D()->Create( + pp_instance(), &k90x90, kNotAlwaysOpaque); + CHECK(graphics2d != kInvalidResource); + PPBInstance()->BindGraphics(pp_instance(), graphics2d); + return graphics2d; +} + +PP_Resource CreateImageData(PP_Size size, ColorPremul pixel_color, void** bmp) { + PP_ImageDataFormat image_format = PPBImageData()->GetNativeImageDataFormat(); + uint32_t formatted_pixel_color = FormatColor(image_format, pixel_color); + PP_Resource image_data = PPBImageData()->Create( + pp_instance(), image_format, &size, kInitToZero); + CHECK(image_data != kInvalidResource); + PP_ImageDataDesc image_desc; + CHECK(PPBImageData()->Describe(image_data, &image_desc) == PP_TRUE); + *bmp = NULL; + *bmp = PPBImageData()->Map(image_data); + CHECK(*bmp != NULL); + uint32_t* bmp_words = static_cast<uint32_t*>(*bmp); + int num_pixels = image_desc.stride / kBytesPerPixel * image_desc.size.height; + for (int i = 0; i < num_pixels; i++) + bmp_words[i] = formatted_pixel_color; + return image_data; +} + +PP_Resource CreateImageData(PP_Size size, ColorPremul pixel_color) { + void* bitmap = NULL; + return CreateImageData(size, pixel_color, &bitmap); +} + +struct FlushData { + FlushData(PP_Resource g, PP_Resource i) : graphics2d(g), image_data(i) {} + PP_Resource graphics2d; + PP_Resource image_data; +}; + +void FlushCallback(void* user_data, int32_t result); +int g_expected_flush_calls = 0; +PP_CompletionCallback MakeTestableFlushCallback(const char* name, + PP_Resource graphics2d, + PP_Resource image_data, + int num_calls) { + g_expected_flush_calls = num_calls; + void* user_data = new FlushData(graphics2d, image_data); + return MakeTestableCompletionCallback(name, FlushCallback, user_data); +} + +void FlushCallback(void* user_data, int32_t result) { + --g_expected_flush_calls; + CHECK(g_expected_flush_calls >= 0); + CHECK(user_data != NULL); + CHECK(result == PP_OK); + + FlushData* data = static_cast<FlushData*>(user_data); + PP_Resource graphics2d = data->graphics2d; + PP_Resource image_data = data->image_data; + if (g_expected_flush_calls == 0) { + PPBCore()->ReleaseResource(graphics2d); + PPBCore()->ReleaseResource(image_data); + delete data; + } else { + PPBGraphics2D()->PaintImageData(graphics2d, image_data, &kOrigin, NULL); + PP_CompletionCallback cc = MakeTestableFlushCallback( + "FlushAnimationCallback", + graphics2d, image_data, g_expected_flush_calls); + CHECK(PP_OK_COMPLETIONPENDING == PPBGraphics2D()->Flush(graphics2d, cc)); + } +} + +bool IsEqualSize(PP_Size size1, PP_Size size2) { + return (size1.width == size2.width && size1.height == size2.height); +} + +bool IsSquareOnScreen(PP_Resource graphics2d, PP_Point origin, PP_Size square, + ColorPremul color) { + PP_Size size; + PP_Bool dummy; + CHECK(PP_TRUE == PPBGraphics2D()->Describe(graphics2d, &size, &dummy)); + + void* bitmap = NULL; + PP_Resource image = CreateImageData(size, kOpaqueBlack, &bitmap); + + PP_ImageDataDesc image_desc; + CHECK(PP_TRUE == PPBImageData()->Describe(image, &image_desc)); + int32_t stride = image_desc.stride / kBytesPerPixel; // width + padding. + uint32_t expected_color = FormatColor(image_desc.format, color); + CHECK(origin.x >= 0 && origin.y >= 0 && + (origin.x + square.width) <= stride && + (origin.y + square.height) <= image_desc.size.height); + + CHECK(PP_TRUE == PPBTestingDev()->ReadImageData(graphics2d, image, &kOrigin)); + bool found_error = false; + for (int y = origin.y; y < origin.y + square.height && !found_error; y++) { + for (int x = origin.x; x < origin.x + square.width && !found_error; x++) { + uint32_t pixel_color = static_cast<uint32_t*>(bitmap)[stride * y + x]; + found_error = (pixel_color != expected_color); + } + } + + PPBCore()->ReleaseResource(image); + return !found_error; +} + +//////////////////////////////////////////////////////////////////////////////// +// Test Cases +//////////////////////////////////////////////////////////////////////////////// + +// Tests PPB_Graphics2D::Create(). +void TestCreate() { + PP_Resource graphics2d = kInvalidResource; + const PPB_Graphics2D* ppb = PPBGraphics2D(); + + // Invalid instance and size -> invalid resource. + graphics2d = ppb->Create(kInvalidInstance, &k30x30, kAlwaysOpaque); + EXPECT(graphics2d == kInvalidResource); + graphics2d = ppb->Create(kInvalidInstance, &k30x30, kNotAlwaysOpaque); + EXPECT(graphics2d == kInvalidResource); + graphics2d = ppb->Create(kNotAnInstance, &k30x30, kAlwaysOpaque); + EXPECT(graphics2d == kInvalidResource); + graphics2d = ppb->Create(kNotAnInstance, &k30x30, kNotAlwaysOpaque); + EXPECT(graphics2d == kInvalidResource); + graphics2d = ppb->Create(pp_instance(), &k100000x100000, kAlwaysOpaque); + EXPECT(graphics2d == kInvalidResource); + graphics2d = ppb->Create(pp_instance(), &k100000x100000, kNotAlwaysOpaque); + EXPECT(graphics2d == kInvalidResource); + graphics2d = ppb->Create(pp_instance(), &kZeroPixels, kAlwaysOpaque); + EXPECT(graphics2d == kInvalidResource); + graphics2d = ppb->Create(pp_instance(), &kZeroPixels, kNotAlwaysOpaque); + EXPECT(graphics2d == kInvalidResource); + graphics2d = ppb->Create(pp_instance(), &kNegativeWidth, kAlwaysOpaque); + EXPECT(graphics2d == kInvalidResource); + graphics2d = ppb->Create(pp_instance(), &kNegativeHeight, kNotAlwaysOpaque); + EXPECT(graphics2d == kInvalidResource); + // NULL size -> Internal error in rpc method. + graphics2d = ppb->Create(pp_instance(), NULL, kAlwaysOpaque); + EXPECT(graphics2d == kInvalidResource); + graphics2d = ppb->Create(pp_instance(), NULL, kNotAlwaysOpaque); + EXPECT(graphics2d == kInvalidResource); + + // Valid instance and size -> valid resource. + graphics2d = ppb->Create(pp_instance(), &kOnePixel, kAlwaysOpaque); + EXPECT(graphics2d != kInvalidResource); + PPBCore()->ReleaseResource(graphics2d); + graphics2d = ppb->Create(pp_instance(), &kOnePixel, kNotAlwaysOpaque); + EXPECT(graphics2d != kInvalidResource); + PPBCore()->ReleaseResource(graphics2d); + graphics2d = ppb->Create(pp_instance(), &k30x30, kAlwaysOpaque); + EXPECT(graphics2d != kInvalidResource); + PPBCore()->ReleaseResource(graphics2d); + graphics2d = ppb->Create(pp_instance(), &k30x30, kNotAlwaysOpaque); + EXPECT(graphics2d != kInvalidResource); + PPBCore()->ReleaseResource(graphics2d); + graphics2d = ppb->Create(pp_instance(), &k2500x2500, kAlwaysOpaque); + EXPECT(graphics2d != kInvalidResource); + PPBCore()->ReleaseResource(graphics2d); + graphics2d = ppb->Create(pp_instance(), &k2500x2500, kNotAlwaysOpaque); + EXPECT(graphics2d != kInvalidResource); + PPBCore()->ReleaseResource(graphics2d); + + TEST_PASSED; +} + +// Tests PPB_Graphics2D::IsGraphics2D(). +void TestIsGraphics2D() { + // Invalid / non-existent / non-Graphics2D resource -> false. + EXPECT(PP_FALSE == PPBGraphics2D()->IsGraphics2D(kInvalidResource)); + EXPECT(PP_FALSE == PPBGraphics2D()->IsGraphics2D(kNotAResource)); + PP_Resource url_loader = PPBURLLoader()->Create(pp_instance()); + CHECK(url_loader != kInvalidResource); + EXPECT(PP_FALSE == PPBGraphics2D()->IsGraphics2D(url_loader)); + PPBCore()->ReleaseResource(url_loader); + + // Current Graphics2D resource -> true. + PP_Resource graphics2d = PPBGraphics2D()->Create( + pp_instance(), &k30x30, kAlwaysOpaque); + EXPECT(PP_TRUE == PPBGraphics2D()->IsGraphics2D(graphics2d)); + + // Released Graphis2D resource -> false. + PPBCore()->ReleaseResource(graphics2d); + EXPECT(PP_FALSE == PPBGraphics2D()->IsGraphics2D(graphics2d)); + + TEST_PASSED; +} + +// Tests PPB_Graphics2D::Describe(). +void TestDescribe() { + PP_Resource graphics2d = kInvalidResource; + const PPB_Graphics2D* ppb = PPBGraphics2D(); + struct PP_Size size = k90x90; + PP_Bool is_always_opaque = PP_TRUE; + + // Valid resource -> output = configuration, true. + graphics2d = ppb->Create(pp_instance(), &k30x30, kNotAlwaysOpaque); + EXPECT(PP_TRUE == ppb->Describe(graphics2d, &size, &is_always_opaque)); + EXPECT(is_always_opaque == PP_FALSE && IsEqualSize(size, k30x30)); + PPBCore()->ReleaseResource(graphics2d); + + graphics2d = ppb->Create(pp_instance(), &k30x30, kAlwaysOpaque); + EXPECT(PP_TRUE == ppb->Describe(graphics2d, &size, &is_always_opaque)); + EXPECT(is_always_opaque == PP_TRUE && IsEqualSize(size, k30x30)); + PPBCore()->ReleaseResource(graphics2d); + + // NULL outputs -> output = unchanged, false. + EXPECT(PP_FALSE == ppb->Describe(graphics2d, NULL, &is_always_opaque)); + EXPECT(PP_FALSE == ppb->Describe(graphics2d, &size, NULL)); + EXPECT(is_always_opaque == PP_TRUE && IsEqualSize(size, k30x30)); + + // Invalid / non-existent resource -> output = 0, false. + EXPECT(PP_FALSE == ppb->Describe(kInvalidResource, &size, &is_always_opaque)); + EXPECT(is_always_opaque == PP_FALSE && IsEqualSize(size, kZeroPixels)); + + is_always_opaque = PP_TRUE; + size = k90x90; + EXPECT(PP_FALSE == ppb->Describe(kNotAResource, &size, &is_always_opaque)); + EXPECT(is_always_opaque == PP_FALSE && IsEqualSize(size, kZeroPixels)); + + TEST_PASSED; +} + +// Tests PPB_Graphics2D::PaintImageData() with specified image rect. +// Draws a blue square in the top right corner. +// Requires a visual inspection. +void TestPaintImageData() { + const PPB_Graphics2D* ppb = PPBGraphics2D(); + PP_Resource graphics2d = CreateGraphics2D_90x90(); + PP_Resource image_data = CreateImageData(k60x60, kSheerBlue); + PP_Resource image_data_noop = CreateImageData(k60x60, kOpaqueBlack); + PP_Rect src_rect = { PP_MakePoint(30, 30), k30x30 }; + PP_Point top_left = PP_MakePoint(30, -30); // target origin = (60, 0); + PP_Point clip_up = PP_MakePoint(0, -31); // target origin = (30, -1) + PP_Point clip_left = PP_MakePoint(-31, 0); // target origin = (-1, 30) + PP_Point clip_right = PP_MakePoint(31, 0); // target origin = (61, 30) + PP_Point clip_down = PP_MakePoint(0, 31); // target origin = (30, 61) + + // Valid args -> copies to backing store and paints to screen after Flush(). + ppb->PaintImageData(graphics2d, image_data, &top_left, &src_rect); + + // Invalid args -> no effect, no crash. + ppb->PaintImageData(kInvalidResource, image_data_noop, &top_left, &src_rect); + ppb->PaintImageData(kNotAResource, image_data_noop, &top_left, &src_rect); + ppb->PaintImageData(graphics2d, kInvalidResource, &top_left, &src_rect); + ppb->PaintImageData(graphics2d, kNotAResource, &top_left, &src_rect); + ppb->PaintImageData(graphics2d, image_data_noop, &clip_up, &src_rect); + ppb->PaintImageData(graphics2d, image_data_noop, &clip_left, &src_rect); + ppb->PaintImageData(graphics2d, image_data_noop, &clip_right, &src_rect); + ppb->PaintImageData(graphics2d, image_data_noop, &clip_down, &src_rect); + ppb->PaintImageData(graphics2d, image_data_noop, &kOrigin, &kBadRect); + // NULL top_left - > Internal error in rpc method. + ppb->PaintImageData(graphics2d, image_data_noop, NULL, &src_rect); + ppb->PaintImageData(kInvalidResource, kNotAResource, NULL, &src_rect); + + // Paints backing store image to screen only after Flush(). + PP_Point top_right = PP_MakePoint(60, 0); + EXPECT(!IsSquareOnScreen(graphics2d, top_right, k30x30, kSheerBlue)); + PP_CompletionCallback cc = MakeTestableFlushCallback( + "PaintImageDataFlushCallback", graphics2d, image_data, 1); + EXPECT(PP_OK_COMPLETIONPENDING == ppb->Flush(graphics2d, cc)); + EXPECT(IsSquareOnScreen(graphics2d, top_right, k30x30, kSheerBlue)); + + // This should have no effect on Flush(). + ppb->PaintImageData(graphics2d, image_data_noop, &top_left, &src_rect); + PPBCore()->ReleaseResource(image_data_noop); + + TEST_PASSED; +} + +// Tests PPB_Graphics2D::PaintImageData() with default rect for entire image. +// Draws a yellow square in the bottom left corner. +// Requires a visual inspection. +void TestPaintImageDataEntire() { + const PPB_Graphics2D* ppb = PPBGraphics2D(); + PP_Resource graphics2d = CreateGraphics2D_90x90(); + PP_Resource image_data = CreateImageData(k30x30, kOpaqueYellow); + PP_Resource image_data_noop = CreateImageData(k30x30, kOpaqueBlack); + PP_Point bottom_left = PP_MakePoint(0, 60); + PP_Point clip_up = PP_MakePoint(0, -1); + PP_Point clip_left = PP_MakePoint(-1, 0); + PP_Point clip_right = PP_MakePoint(61, 0); + PP_Point clip_down = PP_MakePoint(0, 61); + + // Valid args -> copies to backing store. + ppb->PaintImageData(graphics2d, image_data, &bottom_left, kEntireImage); + + // Invalid args -> no effect, no crash. + ppb->PaintImageData( + kInvalidResource, image_data_noop, &bottom_left, kEntireImage); + ppb->PaintImageData( + kNotAResource, image_data_noop, &bottom_left, kEntireImage); + ppb->PaintImageData(graphics2d, kInvalidResource, &bottom_left, kEntireImage); + ppb->PaintImageData(graphics2d, kNotAResource, &bottom_left, kEntireImage); + ppb->PaintImageData(graphics2d, image_data_noop, &clip_up, kEntireImage); + ppb->PaintImageData(graphics2d, image_data_noop, &clip_left, kEntireImage); + ppb->PaintImageData(graphics2d, image_data_noop, &clip_right, kEntireImage); + ppb->PaintImageData(graphics2d, image_data_noop, &clip_down, kEntireImage); + // NULL top_left - > Internal error in rpc method. + ppb->PaintImageData(graphics2d, image_data_noop, NULL, kEntireImage); + ppb->PaintImageData(kInvalidResource, kNotAResource, NULL, kEntireImage); + + // Paints backing store image to the screen only after Flush(). + EXPECT(!IsSquareOnScreen(graphics2d, bottom_left, k30x30, kOpaqueYellow)); + PP_CompletionCallback cc = MakeTestableFlushCallback( + "PaintImageDataEntireFlushCallback", graphics2d, image_data, 1); + EXPECT(PP_OK_COMPLETIONPENDING == ppb->Flush(graphics2d, cc)); + EXPECT(IsSquareOnScreen(graphics2d, bottom_left, k30x30, kOpaqueYellow)); + + // This should have no effect on Flush(). + ppb->PaintImageData(graphics2d, image_data_noop, &bottom_left, kEntireImage); + PPBCore()->ReleaseResource(image_data_noop); + + TEST_PASSED; +} + +// Tests PPB_Graphics2D::Scroll() with specified image rect. +// Draws a white square at the top left, then in the middle. +// Requires a visual inspection. +void TestScroll() { + const PPB_Graphics2D* ppb = PPBGraphics2D(); + PP_Resource graphics2d = CreateGraphics2D_90x90(); + PP_Resource image_data = CreateImageData(k30x30, kOpaqueWhite); + PP_Rect src_rect = { kOrigin, k30x30 }; + PP_Rect clip_rect = { kOrigin, k60x60 }; + PP_Point middle = PP_MakePoint(30, 30); + ppb->PaintImageData(graphics2d, image_data, &kOrigin, &src_rect); + + // Valid args -> scrolls backing store and paints to screen after Flush(). + ppb->Scroll(graphics2d, &clip_rect, &middle); + + // Invalid args -> no effect, no crash. + ppb->Scroll(kInvalidResource, &clip_rect, &middle); + ppb->Scroll(kNotAResource, &clip_rect, &middle); + ppb->Scroll(graphics2d, &clip_rect, NULL); // Internal error in rpc method. + + // Paints backing store image to the sreen only after Flush(). + EXPECT(!IsSquareOnScreen(graphics2d, middle, k30x30, kOpaqueWhite)); + PP_CompletionCallback cc = MakeTestableFlushCallback( + "ScrollFlushCallback", graphics2d, image_data, 1); + EXPECT(PP_OK_COMPLETIONPENDING == ppb->Flush(graphics2d, cc)); + EXPECT(IsSquareOnScreen(graphics2d, middle, k30x30, kOpaqueWhite)); + + TEST_PASSED; +} + +// Tests PPB_Graphics2D::Scroll() with default rect for entire image.. +// Draws a green square in the top left, then bottom right. +// Requires a visual inspection. +void TestScrollEntire() { + const PPB_Graphics2D* ppb = PPBGraphics2D(); + PP_Resource graphics2d = CreateGraphics2D_90x90(); + PP_Resource image_data = CreateImageData(k30x30, kOpaqueGreen); + PP_Point bottom_right = PP_MakePoint(60, 60); + ppb->PaintImageData(graphics2d, image_data, &kOrigin, kEntireImage); + + // Valid args -> scrolls backing store and paints to screen after Flush(). + ppb->Scroll(graphics2d, kEntireImage, &bottom_right); + + // Invalid args -> no crash. + ppb->Scroll(kInvalidResource, kEntireImage, &bottom_right); + ppb->Scroll(kNotAResource, kEntireImage, &bottom_right); + ppb->Scroll(graphics2d, kEntireImage, NULL); // Internal error in rpc method. + + // Paints backing store image to the screen only after Flush(). + EXPECT(!IsSquareOnScreen(graphics2d, bottom_right, k30x30, kOpaqueGreen)); + ppb->Scroll(graphics2d, kEntireImage, &bottom_right); + PP_CompletionCallback cc = MakeTestableFlushCallback( + "ScrollEntireFlushCallback", graphics2d, image_data, 1); + EXPECT(PP_OK_COMPLETIONPENDING == ppb->Flush(graphics2d, cc)); + EXPECT(IsSquareOnScreen(graphics2d, bottom_right, k30x30, kOpaqueGreen)); + + TEST_PASSED; +} + +// Tests PPB_Graphics2D::ReplaceContents(). +// Colors the entire graphics area gray. +// Requires a visual inspection. +void TestReplaceContents() { + PP_Resource graphics2d = CreateGraphics2D_90x90(); + PP_Resource image_data = CreateImageData(k90x90, kSheerGray); + PP_Resource image_data_noop = CreateImageData(k90x90, kOpaqueBlack); + PP_Resource image_data_size_mismatch = CreateImageData(k30x30, kOpaqueBlack); + + // Valid args -> replaces backing store. + PPBGraphics2D()->ReplaceContents(graphics2d, image_data); + + // Invalid args -> no effect, no crash. + PPBGraphics2D()->ReplaceContents(kInvalidResource, image_data_noop); + PPBGraphics2D()->ReplaceContents(kNotAResource, image_data_noop); + PPBGraphics2D()->ReplaceContents(graphics2d, kInvalidResource); + PPBGraphics2D()->ReplaceContents(graphics2d, kNotAResource); + PPBGraphics2D()->ReplaceContents(kInvalidResource, kNotAResource); + PPBGraphics2D()->ReplaceContents(graphics2d, image_data_size_mismatch); + + // Paints backing store image to the screen only after Flush(). + EXPECT(!IsSquareOnScreen(graphics2d, kOrigin, k90x90, kSheerGray)); + PP_CompletionCallback cc = MakeTestableFlushCallback( + "ReplaceContentsFlushCallback", graphics2d, image_data, 1); + EXPECT(PP_OK_COMPLETIONPENDING == PPBGraphics2D()->Flush(graphics2d, cc)); + EXPECT(IsSquareOnScreen(graphics2d, kOrigin, k90x90, kSheerGray)); + + // This should have no effect on Flush(). + PPBGraphics2D()->ReplaceContents(graphics2d, image_data_noop); + PPBCore()->ReleaseResource(image_data_noop); + PPBCore()->ReleaseResource(image_data_size_mismatch); + + TEST_PASSED; +} + +// Tests PPB_Graphics2D::Flush(). +void TestFlush() { + PP_Resource graphics2d = PPBGraphics2D()->Create( + pp_instance(), &k90x90, kAlwaysOpaque); + PP_CompletionCallback cc = MakeTestableFlushCallback( + "FlushCallback", graphics2d, kInvalidResource, 1); + + // Invalid args -> PP_ERROR_BAD..., no callback. + EXPECT(PP_ERROR_BADRESOURCE == PPBGraphics2D()->Flush(kInvalidResource, cc)); + EXPECT(PP_ERROR_BADRESOURCE == PPBGraphics2D()->Flush(kNotAResource, cc)); + EXPECT(PP_ERROR_BADARGUMENT == + PPBGraphics2D()->Flush(graphics2d, PP_BlockUntilComplete())); + + // Valid args -> PP_OK_COMPLETIONPENDING, expect callback. + EXPECT(PP_OK_COMPLETIONPENDING == PPBGraphics2D()->Flush(graphics2d, cc)); + + // Duplicate call -> PP_ERROR_INPROGRESS, no callback. + EXPECT(PP_ERROR_INPROGRESS == PPBGraphics2D()->Flush(graphics2d, cc)); + + TEST_PASSED; +} + +// Tests continious Paint/Flush chaining. +void TestFlushAnimation() { + PP_Resource graphics2d = CreateGraphics2D_90x90(); + PP_Resource image_data = CreateImageData(k30x30, kSheerRed); + + PPBGraphics2D()->PaintImageData(graphics2d, image_data, &kOrigin, NULL); + PP_CompletionCallback cc = MakeTestableFlushCallback( + "FlushAnimationCallback", graphics2d, image_data, 10); + EXPECT(PP_OK_COMPLETIONPENDING == PPBGraphics2D()->Flush(graphics2d, cc)); + + TEST_PASSED; +} + +// Stress testing of a large number of resources. +void TestStress() { + // TODO(nfullagar): Increase the number of resources once the cause of the + // stress test flake is fixed. + const int kManyResources = 100; + PP_Resource graphics2d[kManyResources]; + const PPB_Graphics2D* ppb = PPBGraphics2D(); + + for (int i = 0; i < kManyResources; i++) { + graphics2d[i] = ppb->Create(pp_instance(), &k30x30, kAlwaysOpaque); + EXPECT(graphics2d[i] != kInvalidResource); + EXPECT(PP_TRUE == ppb->IsGraphics2D(graphics2d[i])); + } + for (int i = 0; i < kManyResources; i++) { + PPBCore()->ReleaseResource(graphics2d[i]); + EXPECT(PP_FALSE == PPBGraphics2D()->IsGraphics2D(graphics2d[i])); + } + + TEST_PASSED; +} + +} // namespace + +void SetupTests() { + RegisterTest("TestCreate", TestCreate); + RegisterTest("TestIsGraphics2D", TestIsGraphics2D); + RegisterTest("TestDescribe", TestDescribe); + RegisterTest("TestPaintImageData", TestPaintImageData); + RegisterTest("TestPaintImageDataEntire", TestPaintImageDataEntire); + RegisterTest("TestScroll", TestScroll); + RegisterTest("TestScrollEntire", TestScrollEntire); + RegisterTest("TestReplaceContents", TestReplaceContents); + RegisterTest("TestFlush", TestFlush); + RegisterTest("TestFlushAnimation", TestFlushAnimation); + RegisterTest("TestStress", TestStress); +} + +void SetupPluginInterfaces() { + // none +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_graphics2d/ppapi_ppb_graphics2d.html b/ppapi/native_client/tests/ppapi_browser/ppb_graphics2d/ppapi_ppb_graphics2d.html new file mode 100644 index 0000000..59b7d6d0 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_graphics2d/ppapi_ppb_graphics2d.html @@ -0,0 +1,122 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + <!-- Copyright (c) 2011 Google Inc. All rights reserved. --> + <head> + <META HTTP-EQUIV="Pragma" CONTENT="no-cache" /> + <META HTTP-EQUIV="Expires" CONTENT="-1" /> + <script type="text/javascript" src="nacltest.js"></script> + <script type="application/x-javascript"> +//<![CDATA[ +function setupTests(tester, plugin) { + function testAndAssertStatus(test, name, status) { + var messageListener = test.wrap(function(message) { + plugin.removeEventListener('message', messageListener, false); + test.assertEqual(message.data, name + ':' + status); + test.pass(); + }); + plugin.addEventListener('message', messageListener, false); + plugin.postMessage(name); + } + + function testAndAssertStatusAndCallbacks(test, name, status, callback, calls) { + gotCalls = 0; + var callbackListener = test.wrap(function(message) { + plugin.removeEventListener('message', callbackListener, false); + test.assertEqual(message.data, callback); + if (++gotCalls < calls) + plugin.addEventListener('message', callbackListener, false); + else + test.pass(); + }); + var messageListener = test.wrap(function(message) { + plugin.removeEventListener('message', messageListener, false); + test.assertEqual(message.data, name + ':' + status); + plugin.addEventListener('message', callbackListener, false); + }); + plugin.addEventListener('message', messageListener, false); + plugin.postMessage(name); + } + tester.addAsyncTest('PPB_Graphics2D::Create', function(test) { + testAndAssertStatus(test, 'TestCreate', 'PASSED'); + }); + tester.addAsyncTest('PPB_Graphics2D::IsGraphics2D', function(test) { + testAndAssertStatus(test, 'TestIsGraphics2D', 'PASSED'); + }); + tester.addAsyncTest('PPB_Graphics2D::Describe', function(test) { + testAndAssertStatus(test, 'TestDescribe', 'PASSED'); + }); + // This must be called first because it sets the entire graphics area to gray. + tester.addAsyncTest('PPB_Graphics2D::ReplaceContents', function(test) { + testAndAssertStatusAndCallbacks(test, 'TestReplaceContents', 'PASSED', + 'ReplaceContentsFlushCallback', 1); + }); + // Adds a blue square at the top right. + tester.addAsyncTest('PPB_Graphics2D::PaintImageData', function(test) { + testAndAssertStatusAndCallbacks(test, 'TestPaintImageData', 'PASSED', + 'PaintImageDataFlushCallback', 1); + }); + // Adds a yellow square at the bottom left. + tester.addAsyncTest('PPB_Graphics2D::PaintImageDataEntire', function(test) { + testAndAssertStatusAndCallbacks(test, 'TestPaintImageDataEntire', 'PASSED', + 'PaintImageDataEntireFlushCallback', 1); + }); + // Adds a white square at the top left and then the middle. + tester.addAsyncTest('PPB_Graphics2D::Scroll', function(test) { + testAndAssertStatusAndCallbacks(test, 'TestScroll', 'PASSED', + 'ScrollFlushCallback', 1); + }); + // Adds a green square at the top left (over white) and then the bottom right. + tester.addAsyncTest('PPB_Graphics2D::ScrollEntire', function(test) { + testAndAssertStatusAndCallbacks(test, 'TestScrollEntire', 'PASSED', + 'ScrollEntireFlushCallback', 1); + }); + // Does not alter the image. + tester.addAsyncTest('PPB_Graphics2D::Flush', function(test) { + testAndAssertStatusAndCallbacks(test, 'TestFlush', 'PASSED', + 'FlushCallback', 1); + }); + // Adds a red square at the top left (over green) 10 times. + tester.addAsyncTest('PPB_Graphics2D::FlushAnimation', function(test) { + testAndAssertStatusAndCallbacks(test, 'TestFlushAnimation', 'PASSED', + 'FlushAnimationCallback', 10); + }); + tester.addAsyncTest('PPB_Graphics2D::Stress', function(test) { + testAndAssertStatus(test, 'TestStress', 'PASSED'); + }); +} + //]]> + </script> + <title>PPAPI PPB_Graphics2D Test</title> + </head> + <body> + <h1>PPAPI PPB_Graphics2D Test</h1> + NOTE: requires --enable-pepper-testing + <br><br> + <table> + <tr><td width="120"> Expected Image <td width="120">Actual Image + <tr> + <td> + <table width="90" height="90" bgcolor="#DDDDDD" cellspacing="0"> + <tr><td bgcolor="#FF7777"><td><td bgcolor="#7777FF"> + <tr><td><td bgcolor="#FFFFFF"><td> + <tr><td bgcolor="#FFFF00"><td><td bgcolor="#00FF00"> + </table> + <td> + <embed type="application/x-nacl" id="test_nexe" + name="nacl_module" + src="ppapi_ppb_graphics2d.nmf" + style="background-color:#FFFFFF" + width="90" height="90" /> + <table> + <br> + <script type="text/javascript"> + //<![CDATA[ + var tester = new Tester(); + setupTests(tester, $('test_nexe')); + tester.waitFor($('test_nexe')); + tester.run(); + //]]> + </script> + </body> +</html> diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_graphics2d/ppapi_ppb_graphics2d.nmf b/ppapi/native_client/tests/ppapi_browser/ppb_graphics2d/ppapi_ppb_graphics2d.nmf new file mode 100644 index 0000000..e4d8b1f --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_graphics2d/ppapi_ppb_graphics2d.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_ppb_graphics2d_x86-32.nexe"}, + "x86-64": {"url": "ppapi_ppb_graphics2d_x86-64.nexe"}, + "arm": {"url": "ppapi_ppb_graphics2d_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_graphics3d/nacl.scons b/ppapi/native_client/tests/ppapi_browser/ppb_graphics3d/nacl.scons new file mode 100644 index 0000000..3e07d52 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_graphics3d/nacl.scons @@ -0,0 +1,46 @@ +# -*- python -*- +# 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. +# +# This test uses ppapi_test_lib. + +Import('env') + +env.Prepend(CPPDEFINES=['XP_UNIX']) + +env.Append(CPPPATH=['$SOURCE_ROOT/ppapi/lib/gl/include']) + +nexe = 'ppapi_ppb_graphics3d_${TARGET_FULLARCH}' +env.Alias('ppapi_ppb_graphics3d${PROGSUFFIX}', + ['$STAGING_DIR/%s${PROGSUFFIX}' % nexe]) + +ppapi_ppb_graphics3d_nexe = env.ComponentProgram( + nexe, + [ 'ppapi_ppb_graphics3d.cc' ], + EXTRA_LIBS=['${PPAPI_LIBS}', + 'ppapi_gles2', + 'ppapi_test_lib', + 'platform', # for CHECK + 'pthread', + 'gio', + ]) + +dest_copy = env.Publish(nexe, 'run', + [ 'ppapi_ppb_graphics3d.html', + 'ppapi_ppb_graphics3d.nmf', + env.File('${SCONSTRUCT_DIR}/tools/browser_tester/' + 'browserdata/nacltest.js') ]) + +node = env.PPAPIBrowserTester('ppapi_ppb_graphics3d_browser_test.out', + url='ppapi_ppb_graphics3d.html', + files=[ ppapi_ppb_graphics3d_nexe, + env.File('ppapi_ppb_graphics3d.nmf'), + env.File('ppapi_ppb_graphics3d.html')], + browser_flags=['--enable-accelerated-plugins']) + +env.AddNodeToTestSuite(node, + ['chrome_browser_tests'], + 'run_ppapi_ppb_graphics3d_browser_test', + is_broken=env.PPAPIBrowserTesterIsBroken() or + env.PPAPIGraphics3DIsBroken()) diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_graphics3d/ppapi_ppb_graphics3d.cc b/ppapi/native_client/tests/ppapi_browser/ppb_graphics3d/ppapi_ppb_graphics3d.cc new file mode 100644 index 0000000..f4771b2 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_graphics3d/ppapi_ppb_graphics3d.cc @@ -0,0 +1,152 @@ +// 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. +// +// Test cases for PPB_Graphics3D functions. +// TODO(nfullagar): More comprehensive testing of the PPAPI interface. + +#include <string.h> + +#include <GLES2/gl2.h> + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/tests/ppapi_test_lib/get_browser_interface.h" +#include "native_client/tests/ppapi_test_lib/internal_utils.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" +#include "ppapi/c/dev/pp_graphics_3d_dev.h" +#include "ppapi/c/dev/ppb_graphics_3d_dev.h" +#include "ppapi/c/dev/ppb_opengles_dev.h" +#include "ppapi/c/dev/ppb_testing_dev.h" +#include "ppapi/c/pp_bool.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_point.h" +#include "ppapi/c/pp_rect.h" +#include "ppapi/c/pp_size.h" +#include "ppapi/c/ppb_core.h" +#include "ppapi/c/ppb_image_data.h" +#include "ppapi/c/ppb_instance.h" +#include "ppapi/c/ppb_url_loader.h" +#include "ppapi/lib/gl/gles2/gl2ext_ppapi.h" + +namespace { + +const int kWidth = 320; +const int kHeight = 200; + +//////////////////////////////////////////////////////////////////////////////// +// Test Cases +//////////////////////////////////////////////////////////////////////////////// + +// Tests the Graphics3D interface is available. +void TestGraphics3DInterface() { + EXPECT(PPBGraphics3DDev() != NULL); + TEST_PASSED; +} + +// Tests the OpenGLES interface is available. +void TestOpenGLES2Interface() { + EXPECT(PPBOpenGLES2Dev() != NULL); + TEST_PASSED; +} + +// Tests PPB_Graphics3D::Create(). +void TestCreate() { + int32_t attribs[] = { + PP_GRAPHICS3DATTRIB_WIDTH, kWidth, + PP_GRAPHICS3DATTRIB_HEIGHT, kHeight, + PP_GRAPHICS3DATTRIB_NONE}; + PP_Resource graphics3d_id = PPBGraphics3DDev()-> + Create(pp_instance(), kInvalidResource, attribs); + EXPECT(graphics3d_id != kInvalidResource); + PP_Resource invalid_graphics3d_id = PPBGraphics3DDev()-> + Create(0, kInvalidResource, attribs); + EXPECT(invalid_graphics3d_id == kInvalidResource); + int32_t empty_attribs[] = { + PP_GRAPHICS3DATTRIB_NONE}; + PP_Resource graphics3d_empty_attrib_id = PPBGraphics3DDev()-> + Create(pp_instance(), kInvalidResource, empty_attribs); + EXPECT(graphics3d_empty_attrib_id != kInvalidResource); + PP_Resource graphics3d_null_attrib_id = PPBGraphics3DDev()-> + Create(pp_instance(), kInvalidResource, NULL); + EXPECT(graphics3d_null_attrib_id != kInvalidResource); + TEST_PASSED; +} + +// Tests PPB_Graphics3D::IsGraphics3D(). +void TestIsGraphics3D() { + int32_t attribs[] = { + PP_GRAPHICS3DATTRIB_WIDTH, kWidth, + PP_GRAPHICS3DATTRIB_HEIGHT, kHeight, + PP_GRAPHICS3DATTRIB_NONE}; + PP_Resource graphics3d_id = PPBGraphics3DDev()-> + Create(pp_instance(), kInvalidResource, attribs); + EXPECT(graphics3d_id != kInvalidResource); + EXPECT(PPBGraphics3DDev()->IsGraphics3D(graphics3d_id) == PP_TRUE); + TEST_PASSED; +} + +struct RenderInfo { + PP_Resource graphics3d_id; + int32_t frame_counter; + int32_t frame_end; +}; + +void SwapCallback(void* user_data, int32_t result) { + EXPECT(result == PP_OK); + RenderInfo* info = static_cast<RenderInfo *>(user_data); + // Set graphics3d_id to the main context, so we can use normal gl style calls + // instead of going through the PPAPI PPBOpenGLES2 interface. + glSetCurrentContextPPAPI(info->graphics3d_id); + glViewport(0, 0, kWidth, kHeight); + float blue = float(info->frame_counter) / float(info->frame_end); + glClearColor(0.0f, 0.0f, blue, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + ++info->frame_counter; + if (info->frame_counter < info->frame_end) { + PP_CompletionCallback cc = PP_MakeCompletionCallback(SwapCallback, info); + int32_t result = PPBGraphics3DDev()->SwapBuffers(info->graphics3d_id, cc); + CHECK(PP_OK_COMPLETIONPENDING == result); + } else { + delete info; + } + glSetCurrentContextPPAPI(0); +} + +// Tests PPB_Graphics3D::SwapBuffers(). This test will render a visible +// result to the screen -- fading in a solid blue rectangle. +void TestSwapBuffers() { + int32_t attribs[] = { + PP_GRAPHICS3DATTRIB_WIDTH, kWidth, + PP_GRAPHICS3DATTRIB_HEIGHT, kHeight, + PP_GRAPHICS3DATTRIB_NONE}; + PP_Resource graphics3d_id = PPBGraphics3DDev()-> + Create(pp_instance(), kInvalidResource, attribs); + EXPECT(graphics3d_id != kInvalidResource); + int32_t success = PPBInstance()->BindGraphics(pp_instance(), graphics3d_id); + EXPECT(success == PP_TRUE); + RenderInfo* render_info = new RenderInfo; + render_info->graphics3d_id = graphics3d_id; + render_info->frame_counter = 0; + render_info->frame_end = 256; + glInitializePPAPI(ppb_get_interface()); + PP_CompletionCallback cc = MakeTestableCompletionCallback( + "SwapBufferCallback", SwapCallback, render_info); + PPBCore()->CallOnMainThread(0, cc, PP_OK); + TEST_PASSED; +} + +} // namespace + +void SetupTests() { + RegisterTest("TestGraphics3DInterface", TestGraphics3DInterface); + RegisterTest("TestOpenGLES2Interface", TestOpenGLES2Interface); + RegisterTest("TestCreate", TestCreate); + RegisterTest("TestIsGraphics3D", TestIsGraphics3D); + RegisterTest("TestSwapBuffers", TestSwapBuffers); +} + +void SetupPluginInterfaces() { + // none +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_graphics3d/ppapi_ppb_graphics3d.html b/ppapi/native_client/tests/ppapi_browser/ppb_graphics3d/ppapi_ppb_graphics3d.html new file mode 100644 index 0000000..a3596d8 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_graphics3d/ppapi_ppb_graphics3d.html @@ -0,0 +1,63 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + <!-- Copyright (c) 2011 Google Inc. All rights reserved. --> + <head> + <META HTTP-EQUIV="Pragma" CONTENT="no-cache" /> + <META HTTP-EQUIV="Expires" CONTENT="-1" /> + <script type="text/javascript" src="nacltest.js"></script> + <script type="application/x-javascript"> +//<![CDATA[ +function setupTests(tester, plugin) { + function testAndAssertStatus(test, name, status) { + test.expectEvent(plugin, 'message', function(message) { + test.assertEqual(message.data, name + ':' + status); + test.pass(); + }); + plugin.postMessage(name); + } + + tester.addAsyncTest('PPB_Graphics3D Interface', function(test) { + testAndAssertStatus(test, 'TestGraphics3DInterface', 'PASSED'); + }); + tester.addAsyncTest('PPB_OpenGLES2 Interface', function(test) { + testAndAssertStatus(test, 'TestOpenGLES2Interface', 'PASSED'); + }); + tester.addAsyncTest('PPB_Graphics3D::Create', function(test) { + testAndAssertStatus(test, 'TestCreate', 'PASSED'); + }); + tester.addAsyncTest('PPB_Graphics3D::IsGraphics3D', function(test) { + testAndAssertStatus(test, 'TestIsGraphics3D', 'PASSED'); + }); + tester.addAsyncTest('PPB_Graphics3D::SwapBuffers', function(test) { + testAndAssertStatus(test, 'TestSwapBuffers', 'PASSED'); + }); +} + //]]> + </script> + <title>PPAPI PPB_Graphics3D Test</title> + </head> + <body> + <h1>PPAPI PPB_Graphics3D Test</h1> + NOTE: requires --enable-pepper-testing --enable-accelerated-plugins + <br> + The rectangle below should fade from black to blue. + <br><br> + <tr> + <td> + <embed type="application/x-nacl" id="test_nexe" + name="nacl_module" + src="ppapi_ppb_graphics3d.nmf" + style="background-color:#FFFFFF" + width="320" height="200" /> + <br> + <script type="text/javascript"> + //<![CDATA[ + var tester = new Tester(); + setupTests(tester, $('test_nexe')); + tester.waitFor($('test_nexe')); + tester.run(); + //]]> + </script> + </body> +</html> diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_graphics3d/ppapi_ppb_graphics3d.nmf b/ppapi/native_client/tests/ppapi_browser/ppb_graphics3d/ppapi_ppb_graphics3d.nmf new file mode 100644 index 0000000..34e9ec0 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_graphics3d/ppapi_ppb_graphics3d.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_ppb_graphics3d_x86-32.nexe"}, + "x86-64": {"url": "ppapi_ppb_graphics3d_x86-64.nexe"}, + "arm": {"url": "ppapi_ppb_graphics3d_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_image_data/nacl.scons b/ppapi/native_client/tests/ppapi_browser/ppb_image_data/nacl.scons new file mode 100644 index 0000000..8b41021 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_image_data/nacl.scons @@ -0,0 +1,39 @@ +# -*- python -*- +# 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. +# +# This test uses ppapi_test_lib. + +Import('env') + +env.Prepend(CPPDEFINES=['XP_UNIX']) + +nexe = 'ppapi_ppb_image_data_${TARGET_FULLARCH}' +env.Alias('ppapi_ppb_image_data${PROGSUFFIX}', + ['$STAGING_DIR/%s${PROGSUFFIX}' % nexe]) + +env.ComponentProgram( + nexe, + ['ppapi_ppb_image_data.cc'], + EXTRA_LIBS=['${PPAPI_LIBS}', + 'ppapi_test_lib', + 'platform', # for CHECK + 'pthread', + 'gio', + ]) + +env.Publish(nexe, 'run', + [ 'ppapi_ppb_image_data.html', + 'ppapi_ppb_image_data.nmf', + env.File('${SCONSTRUCT_DIR}/tools/browser_tester/' + 'browserdata/nacltest.js') ]) + +node = env.PPAPIBrowserTester('ppapi_ppb_image_data_browser_test.out', + url='ppapi_ppb_image_data.html', + files=env.ExtractPublishedFiles(nexe)) + +env.AddNodeToTestSuite(node, + ['chrome_browser_tests'], + 'run_ppapi_ppb_image_data_browser_test', + is_broken=env.PPAPIBrowserTesterIsBroken()) diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_image_data/ppapi_ppb_image_data.cc b/ppapi/native_client/tests/ppapi_browser/ppb_image_data/ppapi_ppb_image_data.cc new file mode 100644 index 0000000..e11f989 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_image_data/ppapi_ppb_image_data.cc @@ -0,0 +1,342 @@ +// 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. +// +// Test cases for PPB_ImageData functions. +// +// TODO(polina): use PPB_Testing for additional automatic validation. + +#include <string.h> + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/tests/ppapi_test_lib/get_browser_interface.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" +#include "ppapi/c/pp_bool.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_point.h" +#include "ppapi/c/pp_rect.h" +#include "ppapi/c/pp_size.h" +#include "ppapi/c/ppb_core.h" +#include "ppapi/c/ppb_graphics_2d.h" +#include "ppapi/c/ppb_image_data.h" +#include "ppapi/c/ppb_instance.h" +#include "ppapi/c/ppb_url_loader.h" + +namespace { + +const int kPixelSizeInBytes = 4; +const PP_Size kOnePixelImageSize = PP_MakeSize(1, 1); +const PP_Size kSmallImageSize = PP_MakeSize(30, 30); +const PP_Size kLargeImageSize = PP_MakeSize(2048, 2048); +const PP_Size kValidImageSize[] = { + kOnePixelImageSize, + kSmallImageSize, + kLargeImageSize +}; +const int kNumValidImages = sizeof(kValidImageSize) / sizeof(PP_Size); +const PP_Size kInvalidImageSize[] = { + PP_MakeSize(100000000, 100000000), + PP_MakeSize(-100000000, 100000000), + PP_MakeSize(-100, 100000000), + PP_MakeSize(100, -100000000), + PP_MakeSize(-100, 100), + PP_MakeSize(-100, -100), + PP_MakeSize(0, 0), + PP_MakeSize(0, 100), + PP_MakeSize(100, 0) +}; +const int kNumInvalidImages = sizeof(kInvalidImageSize) / sizeof(PP_Size); + +union BogusFormat { + int bogus; + PP_ImageDataFormat format; +}; + +bool IsEqualSize(PP_Size size1, PP_Size size2) { + return (size1.width == size2.width && size1.height == size2.height); +} + +//////////////////////////////////////////////////////////////////////////////// +// Test Cases +//////////////////////////////////////////////////////////////////////////////// + +// Tests PPB_ImageData::GetNativeImageDataFormat(). +void TestGetNativeImageDataFormat() { + bool test_passed = false; + PP_ImageDataFormat format; + // TODO(nfullagar): If new formats are added after this test is written, + // then the switch statement below will need to be updated, and additional + // testing will need to be done in the other test cases below. + // Also, new formats could introduce new pixel sizeis (in bytes), which + // could affect some of the stride checks. + format = PPBImageData()->GetNativeImageDataFormat(); + switch (format) { + case PP_IMAGEDATAFORMAT_BGRA_PREMUL: + case PP_IMAGEDATAFORMAT_RGBA_PREMUL: + test_passed = true; + } + EXPECT(test_passed); + TEST_PASSED; +} + +// Tests PPB_ImageData::IsImageDataFormatSupported(). +void TestIsImageDataFormatSupported() { + PP_ImageDataFormat format; + BogusFormat bogus; + format = PPBImageData()->GetNativeImageDataFormat(); + // EXPECT the format recommended by the browser is supported. + EXPECT(PP_TRUE == PPBImageData()->IsImageDataFormatSupported(format)); + // Invoke with known formats, should not crash. + PPBImageData()->IsImageDataFormatSupported(PP_IMAGEDATAFORMAT_BGRA_PREMUL); + PPBImageData()->IsImageDataFormatSupported(PP_IMAGEDATAFORMAT_RGBA_PREMUL); + // Make up invalid enums and verify they are not supported. + bogus.bogus = -1; + EXPECT(PP_FALSE == PPBImageData()-> + IsImageDataFormatSupported(bogus.format)); + bogus.bogus = 123; + EXPECT(PP_FALSE == PPBImageData()-> + IsImageDataFormatSupported(bogus.format)); + TEST_PASSED; +} + +// Tests PPB_ImageData::Create(). +void TestCreate() { + PP_Resource image_data = kInvalidResource; + BogusFormat bogus; + // Invalid instance and valid size -> expect an invalid resource. + image_data = PPBImageData()->Create(kInvalidInstance, + PP_IMAGEDATAFORMAT_BGRA_PREMUL, &kSmallImageSize, PP_FALSE); + EXPECT(image_data == kInvalidResource); + image_data = PPBImageData()->Create(kInvalidInstance, + PP_IMAGEDATAFORMAT_RGBA_PREMUL, &kSmallImageSize, PP_FALSE); + EXPECT(image_data == kInvalidResource); + image_data = PPBImageData()->Create(kInvalidInstance, + PP_IMAGEDATAFORMAT_BGRA_PREMUL, &kSmallImageSize, PP_TRUE); + EXPECT(image_data == kInvalidResource); + image_data = PPBImageData()->Create(kInvalidInstance, + PP_IMAGEDATAFORMAT_RGBA_PREMUL, &kSmallImageSize, PP_TRUE); + EXPECT(image_data == kInvalidResource); + // NULL size -> Internal error in rpc method, expect an invalid resource. + image_data = PPBImageData()->Create(kInvalidInstance, + PP_IMAGEDATAFORMAT_BGRA_PREMUL, NULL, PP_FALSE); + EXPECT(image_data == kInvalidResource); + image_data = PPBImageData()->Create(kInvalidInstance, + PP_IMAGEDATAFORMAT_RGBA_PREMUL, NULL, PP_FALSE); + EXPECT(image_data == kInvalidResource); + image_data = PPBImageData()->Create(kInvalidInstance, + PP_IMAGEDATAFORMAT_BGRA_PREMUL, NULL, PP_TRUE); + EXPECT(image_data == kInvalidResource); + image_data = PPBImageData()->Create(kInvalidInstance, + PP_IMAGEDATAFORMAT_RGBA_PREMUL, NULL, PP_TRUE); + EXPECT(image_data == kInvalidResource); + // bogus image format -> expect an invalid resource. + bogus.bogus = -1; + image_data = PPBImageData()->Create(pp_instance(), bogus.format, + &kSmallImageSize, PP_FALSE); + EXPECT(image_data == kInvalidResource); + bogus.bogus = 123; + image_data = PPBImageData()->Create(pp_instance(), bogus.format, + &kSmallImageSize, PP_TRUE); + EXPECT(image_data == kInvalidResource); + + PP_Bool kPixelFill[] = {PP_FALSE, PP_TRUE}; + int kNumPixelFill = sizeof(kPixelFill) / sizeof(PP_Bool); + PP_ImageDataFormat native_format = PPBImageData()->GetNativeImageDataFormat(); + for (int j = 0; j < kNumPixelFill; ++j) { + // Valid instance and valid image size should generate a valid resource. + for (int i = 0; i < kNumValidImages; ++i) { + image_data = PPBImageData()->Create(pp_instance(), native_format, + &kValidImageSize[i], kPixelFill[j]); + EXPECT(image_data != kInvalidResource); + PPBCore()->ReleaseResource(image_data); + } + // Valid instance and invalid size should generate an invalid resource. + for (int i = 0; i < kNumInvalidImages; ++i) { + image_data = PPBImageData()->Create(pp_instance(), native_format, + &kInvalidImageSize[i], kPixelFill[j]); + EXPECT(image_data == kInvalidResource); + } + } + TEST_PASSED; +} + +// Tests PPB_ImageData::IsImageData(). +void TestIsImageData() { + // Invalid / non-existent / non-ImageData resource -> false. + EXPECT(PP_FALSE == PPBImageData()->IsImageData(kInvalidResource)); + EXPECT(PP_FALSE == PPBImageData()->IsImageData(kNotAResource)); + PP_Resource url_loader = PPBURLLoader()->Create(pp_instance()); + CHECK(url_loader != kInvalidResource); + EXPECT(PP_FALSE == PPBImageData()->IsImageData(url_loader)); + PPBCore()->ReleaseResource(url_loader); + + PP_ImageDataFormat format = PPBImageData()->GetNativeImageDataFormat(); + + // Created ImageData resource -> true. + PP_Resource image_data = PPBImageData()->Create( + pp_instance(), format, &kSmallImageSize, PP_TRUE); + EXPECT(PP_TRUE == PPBImageData()->IsImageData(image_data)); + + // Released ImageData resource -> false. + PPBCore()->ReleaseResource(image_data); + EXPECT(PP_FALSE == PPBImageData()->IsImageData(image_data)); + TEST_PASSED; +} + +// Tests PPB_ImageData::Describe(). +void TestDescribe() { + PP_Resource image_data = kInvalidResource; + PP_ImageDataFormat format = PPBImageData()->GetNativeImageDataFormat(); + PP_ImageDataDesc description; + + // Valid resource -> output = configuration, true. + image_data = PPBImageData()->Create(pp_instance(), format, &kSmallImageSize, + PP_FALSE); + memset(&description, 0, sizeof(description)); + EXPECT(PP_TRUE == PPBImageData()->Describe(image_data, &description)); + EXPECT(description.format == format); + EXPECT(IsEqualSize(description.size, kSmallImageSize)); + EXPECT(description.stride >= description.size.width * + kPixelSizeInBytes); + PPBCore()->ReleaseResource(image_data); + + image_data = PPBImageData()->Create(pp_instance(), format, &kSmallImageSize, + PP_TRUE); + memset(&description, 0, sizeof(description)); + EXPECT(PP_TRUE == PPBImageData()->Describe(image_data, &description)); + EXPECT(description.format == format); + EXPECT(IsEqualSize(description.size, kSmallImageSize)); + EXPECT(description.stride >= description.size.width * kPixelSizeInBytes); + PPBCore()->ReleaseResource(image_data); + + // NULL outputs -> output = unchanged, false. + EXPECT(PP_FALSE == PPBImageData()->Describe(image_data, NULL)); + + // Invalid / non-existent resource -> output = 0, false. + memset(&description, 0, sizeof(description)); + EXPECT(PP_FALSE == PPBImageData()->Describe(kInvalidResource, &description)); + EXPECT(IsEqualSize(description.size, PP_MakeSize(0, 0))); + EXPECT(PP_FALSE == PPBImageData()->Describe(kNotAResource, &description)); + EXPECT(IsEqualSize(description.size, PP_MakeSize(0, 0))); + TEST_PASSED; +} + +// Tests PPB_ImageData::Map() & PPB_ImageData::Unmap(). +void TestMapUnmap() { + PP_Resource image_data = kInvalidResource; + PP_ImageDataFormat format = PPBImageData()->GetNativeImageDataFormat(); + PP_ImageDataDesc description; + uint8_t *pixel_byte_ptr; + uint8_t *pixel_byte_ptr2; + uint8_t pixel_bytes_or_together; + image_data = PPBImageData()->Create(pp_instance(), format, &kSmallImageSize, + PP_TRUE); + EXPECT(PP_TRUE == PPBImageData()->Describe(image_data, &description)); + int image_size_in_bytes = description.stride * description.size.height; + pixel_byte_ptr = static_cast<uint8_t *>(PPBImageData()->Map(image_data)); + EXPECT(NULL != pixel_byte_ptr); + pixel_bytes_or_together = 0; + // The image was created with a request to zero fill, so verify that + // memory is zero filled. + for (int i = 0; i < image_size_in_bytes; ++i) { + pixel_bytes_or_together = pixel_bytes_or_together | pixel_byte_ptr[i]; + } + EXPECT(0 == pixel_bytes_or_together); + PPBImageData()->Unmap(image_data); + PPBCore()->ReleaseResource(image_data); + // The following shouldn't crash -- it attempts to map an image resource more + // than once, then it attempts to release the resource, then calls unmap with + // the released resource. It then attempts to re-map the resource, which + // should return a NULL pointer. + image_data = PPBImageData()->Create(pp_instance(), format, &kSmallImageSize, + PP_TRUE); + pixel_byte_ptr = static_cast<uint8_t *>(PPBImageData()->Map(image_data)); + EXPECT(NULL != pixel_byte_ptr); + pixel_byte_ptr2 = static_cast<uint8_t *>(PPBImageData()->Map(image_data)); + EXPECT(pixel_byte_ptr == pixel_byte_ptr2); + PPBCore()->ReleaseResource(image_data); + PPBImageData()->Unmap(image_data); + pixel_byte_ptr = static_cast<uint8_t *>(PPBImageData()->Map(image_data)); + EXPECT(NULL == pixel_byte_ptr); + // Attempt to call map/unmap with a few other non-image data resources. + pixel_byte_ptr = static_cast<uint8_t *>(PPBImageData()-> + Map(kInvalidResource)); + EXPECT(NULL == pixel_byte_ptr); + PPBImageData()->Unmap(kInvalidResource); + PP_Resource url_loader = PPBURLLoader()->Create(pp_instance()); + CHECK(url_loader != kInvalidResource); + pixel_byte_ptr = static_cast<uint8_t *>(PPBImageData()->Map(url_loader)); + EXPECT(NULL == pixel_byte_ptr); + PPBCore()->ReleaseResource(url_loader); + TEST_PASSED; +} + +// Stress testing of a large number of resources. +void TestStress() { + // TODO(nfullagar): Increase the number of resources once the cause of the + // stress test flake is fixed. + const int kManyResources = 100; + const int kManyLargeResources = 100; + PP_Resource image_data[kManyResources]; + PP_Resource large_image_data; + PP_ImageDataFormat format = PPBImageData()->GetNativeImageDataFormat(); + + // Create a large number of co-existing memory mapped small images. + for (int i = 0; i < kManyResources; ++i) { + image_data[i] = PPBImageData()->Create(pp_instance(), format, + &kSmallImageSize, PP_TRUE); + EXPECT(image_data[i] != kInvalidResource); + // Check to see if resource id is duplicate. + // TODO(nfullagar): This could be done faster if the test needs to increase + // the number of resources to create. + for (int j = 0; j < i; ++j) { + EXPECT(image_data[j] != image_data[i]); + } + EXPECT(PP_TRUE == PPBImageData()->IsImageData(image_data[i])); + EXPECT(NULL != PPBImageData()->Map(image_data[i])); + } + + // A large number of create-map-unmap-release large images. + // Only one large image exists at a time; make sure memory space isn't + // exhausted. + // TODO(nfullagar): Some platforms (notably 32-bit ones) are unable to + // recycle a large number of large resources. This might be related to: + // http://code.google.com/p/chromium/issues/detail?id=87445 + for (int i = 0; i < kManyLargeResources; i++) { + large_image_data = PPBImageData()->Create(pp_instance(), format, + &kLargeImageSize, PP_TRUE); + EXPECT(large_image_data != kInvalidResource); + EXPECT(PP_TRUE == PPBImageData()->IsImageData(large_image_data)); + EXPECT(NULL != PPBImageData()->Map(large_image_data)); + PPBImageData()->Unmap(large_image_data); + PPBCore()->ReleaseResource(large_image_data); + EXPECT(PP_FALSE == PPBImageData()->IsImageData(large_image_data)); + } + + // Go back and unmap the smaller images. + for (int i = 0; i < kManyResources; i++) { + PPBImageData()->Unmap(image_data[i]); + EXPECT(PP_TRUE == PPBImageData()->IsImageData(image_data[i])); + PPBCore()->ReleaseResource(image_data[i]); + EXPECT(PP_FALSE == PPBImageData()->IsImageData(image_data[i])); + } + + TEST_PASSED; +} +} // namespace + +void SetupTests() { + RegisterTest("TestGetNativeImageDataFormat", TestGetNativeImageDataFormat); + RegisterTest("TestIsImageDataFormatSupported", + TestIsImageDataFormatSupported); + RegisterTest("TestCreate", TestCreate); + RegisterTest("TestIsImageData", TestIsImageData); + RegisterTest("TestDescribe", TestDescribe); + RegisterTest("TestMapUnmap", TestMapUnmap); + RegisterTest("TestStress", TestStress); +} + +void SetupPluginInterfaces() { + // none +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_image_data/ppapi_ppb_image_data.html b/ppapi/native_client/tests/ppapi_browser/ppb_image_data/ppapi_ppb_image_data.html new file mode 100644 index 0000000..316fd614 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_image_data/ppapi_ppb_image_data.html @@ -0,0 +1,75 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + <!-- Copyright (c) 2011 Google Inc. All rights reserved. --> + <head> + <META HTTP-EQUIV="Pragma" CONTENT="no-cache" /> + <META HTTP-EQUIV="Expires" CONTENT="-1" /> + <script type="text/javascript" src="nacltest.js"></script> + <script type="application/x-javascript"> +//<![CDATA[ +function setupTests(tester, plugin) { + function testAndAssertStatus(test, name, status) { + var messageListener = test.wrap(function(message) { + plugin.removeEventListener('message', messageListener, false); + test.assertEqual(message.data, name + ':' + status); + test.pass(); + }); + plugin.addEventListener('message', messageListener, false); + plugin.postMessage(name); + } + + tester.addAsyncTest('PPB_ImageData::GetNativeImageDataFormat', + function(test) { + testAndAssertStatus(test, 'TestGetNativeImageDataFormat', 'PASSED'); + } + ); + tester.addAsyncTest('PPB_ImageData::IsImageDataFormatSupported', + function(test) { + testAndAssertStatus(test, 'TestIsImageDataFormatSupported', 'PASSED'); + } + ); + tester.addAsyncTest('PPB_ImageData::Create', function(test) { + testAndAssertStatus(test, 'TestCreate', 'PASSED'); + }); + tester.addAsyncTest('PPB_ImageData::IsImageData', function(test) { + testAndAssertStatus(test, 'TestIsImageData', 'PASSED'); + }); + tester.addAsyncTest('PPB_ImageData::Describe', function(test) { + testAndAssertStatus(test, 'TestDescribe', 'PASSED'); + }); + tester.addAsyncTest('PPB_ImageData::MapUnmap', function(test) { + testAndAssertStatus(test, 'TestMapUnmap', 'PASSED'); + }); + tester.addAsyncTest('PPB_ImageData::Stress', function(test) { + testAndAssertStatus(test, 'TestStress', 'PASSED'); + }); +} +//]]> + </script> + <title>PPAPI PPB_ImageData Test</title> + </head> + <body> + <h1>PPAPI PPB_ImageData Test</h1> + NOTE: requires --enable-pepper-testing + <br><br> + <table> + <tr> + <td> + <embed type="application/x-nacl" id="test_nexe" + name="nacl_module" + src="ppapi_ppb_image_data.nmf" + style="background-color:#FFFFFF" + width="90" height="90" /> + <table> + <br> + <script type="text/javascript"> + //<![CDATA[ + var tester = new Tester(); + setupTests(tester, $('test_nexe')); + tester.waitFor($('test_nexe')); + tester.run(); + //]]> + </script> + </body> +</html> diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_image_data/ppapi_ppb_image_data.nmf b/ppapi/native_client/tests/ppapi_browser/ppb_image_data/ppapi_ppb_image_data.nmf new file mode 100644 index 0000000..fc7b568 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_image_data/ppapi_ppb_image_data.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_ppb_image_data_x86-32.nexe"}, + "x86-64": {"url": "ppapi_ppb_image_data_x86-64.nexe"}, + "arm": {"url": "ppapi_ppb_image_data_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_instance/nacl.scons b/ppapi/native_client/tests/ppapi_browser/ppb_instance/nacl.scons new file mode 100644 index 0000000..bf8727f5 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_instance/nacl.scons @@ -0,0 +1,38 @@ +# -*- python -*- +# 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. +# +# This test uses ppapi_test_lib. + +Import('env') + +env.Prepend(CPPDEFINES=['XP_UNIX']) + +nexe = 'ppapi_ppb_instance_%s' % env.get('TARGET_FULLARCH') +env.Alias('ppapi_ppb_instance${PROGSUFFIX}', ['$STAGING_DIR/%s${PROGSUFFIX}' % nexe]) + +env.ComponentProgram( + nexe, + ['ppapi_ppb_instance.cc'], + EXTRA_LIBS=['${PPAPI_LIBS}', + 'ppapi_test_lib', + 'pthread', + 'platform', + 'gio']) + +# Note that the html is required to run this program. +env.Publish(nexe, 'run', + ['ppapi_ppb_instance.html', + 'ppapi_ppb_instance.nmf', + env.File('${SCONSTRUCT_DIR}/tools/browser_tester/' + 'browserdata/nacltest.js')]) + +node = env.PPAPIBrowserTester('ppapi_ppb_instance_browser_test.out', + url='ppapi_ppb_instance.html', + files=env.ExtractPublishedFiles(nexe)) + +env.AddNodeToTestSuite(node, + ['chrome_browser_tests'], + 'run_ppapi_ppb_instance_browser_test', + is_broken=env.PPAPIBrowserTesterIsBroken()) diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_instance/ppapi_ppb_instance.cc b/ppapi/native_client/tests/ppapi_browser/ppb_instance/ppapi_ppb_instance.cc new file mode 100644 index 0000000..cfb5210 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_instance/ppapi_ppb_instance.cc @@ -0,0 +1,81 @@ +// 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/platform/nacl_check.h" +#include "native_client/tests/ppapi_test_lib/get_browser_interface.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" + +#include "ppapi/c/pp_size.h" +#include "ppapi/c/ppb_image_data.h" +#include "ppapi/c/ppb_instance.h" +#include "ppapi/c/ppb_graphics_2d.h" + +namespace { + + +// Tests PPB_Instance::IsFullFrame(). +void TestIsFullFrame() { + // Note: IsFullFrame returning PP_TRUE is only possible when a plugin + // is a content handler. For coverage, see: + // tests/ppapi_browser/extension_mime_handler/ + PP_Bool full_frame = PPBInstance()->IsFullFrame(pp_instance()); + EXPECT(full_frame == PP_FALSE); + + full_frame = PPBInstance()->IsFullFrame(kInvalidInstance); + EXPECT(full_frame == PP_FALSE); + + TEST_PASSED; +} + +void TestBindGraphics() { + PP_Size size = PP_MakeSize(100, 100); + + PP_Resource graphics1 = PPBGraphics2D()->Create( + pp_instance(), &size, PP_TRUE); + PP_Resource graphics2 = PPBGraphics2D()->Create( + pp_instance(), &size, PP_TRUE); + + EXPECT(graphics1 != kInvalidResource); + EXPECT(graphics2 != kInvalidResource); + + PP_Bool ret = PPBInstance()->BindGraphics(pp_instance(), graphics1); + EXPECT(ret == PP_TRUE); + + // We should be allowed to replace one device with another. + ret = PPBInstance()->BindGraphics(pp_instance(), graphics2); + EXPECT(ret == PP_TRUE); + + // This should fail because instance is not valid. + ret = PPBInstance()->BindGraphics(kInvalidInstance, graphics1); + EXPECT(ret == PP_FALSE); + + // This should fail because instance is not valid and graphics2 is bound. + ret = PPBInstance()->BindGraphics(kInvalidInstance, graphics2); + EXPECT(ret == PP_FALSE); + + // This is not a failure, binding resource 0 simply unbinds all devices. + ret = PPBInstance()->BindGraphics(pp_instance(), kInvalidResource); + EXPECT(ret == PP_TRUE); + + PP_Resource image_data = PPBImageData()->Create( + pp_instance(), PP_IMAGEDATAFORMAT_RGBA_PREMUL, &size, PP_FALSE); + EXPECT(image_data != kInvalidResource); + + // This should fail because the resource is the wrong type. + ret = PPBInstance()->BindGraphics(pp_instance(), image_data); + EXPECT(ret == PP_FALSE); + + TEST_PASSED; +} + +} // namespace + +void SetupTests() { + RegisterTest("TestIsFullFrame", TestIsFullFrame); + RegisterTest("TestBindGraphics", TestBindGraphics); +} + +void SetupPluginInterfaces() { + // none +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_instance/ppapi_ppb_instance.html b/ppapi/native_client/tests/ppapi_browser/ppb_instance/ppapi_ppb_instance.html new file mode 100644 index 0000000..d39d0449 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_instance/ppapi_ppb_instance.html @@ -0,0 +1,63 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + <!-- Copyright 2011 Google Inc. All rights reserved. --> + <head> + <META HTTP-EQUIV="Pragma" CONTENT="no-cache" /> + <META HTTP-EQUIV="Expires" CONTENT="-1" /> + <script type="text/javascript" src="nacltest.js"></script> + <script type="application/x-javascript"> + //<![CDATA[ + function setupTests(tester, plugin) { + // This function takes an array of messages and asserts that the nexe + // calls PostMessage with each of these messages, in order. + function expectMessages(test, plugin, messages) { + test.assert(messages.length > 0, 'Must provide at least one message'); + var listener = test.wrap(function(message) { + plugin.removeEventListener('message', listener, false); + test.assertEqual(message.data, messages.shift()); + if (messages.length == 0) { + test.pass(); + } else { + plugin.addEventListener('message', listener, false); + } + }); + plugin.addEventListener('message', listener, false); + } + + function addTest(test_name, responses) { + if (responses === undefined) { + responses = []; + } + var expected_messages = [test_name + ':PASSED'].concat(responses); + tester.addAsyncTest('PPB_Instance::' + test_name, function(test) { + expectMessages(test, plugin, expected_messages); + plugin.postMessage(test_name) + }); + } + + addTest('TestIsFullFrame'); + addTest('TestBindGraphics'); + } + //]]> + </script> + <title>PPAPI PPB_Instance Test</title> + </head> + <body> + <h1>PPAPI PPB_Instance Test</h1> + + <embed type="application/x-nacl" id="test_nexe" + name="nacl_module" + src="ppapi_ppb_instance.nmf" + width="0" height="0" /> + + <script type="text/javascript"> + //<![CDATA[ + var tester = new Tester(); + setupTests(tester, $('test_nexe')); + tester.waitFor($('test_nexe')); + tester.run(); + //]]> + </script> + </body> +</html> diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_instance/ppapi_ppb_instance.nmf b/ppapi/native_client/tests/ppapi_browser/ppb_instance/ppapi_ppb_instance.nmf new file mode 100644 index 0000000..456c513 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_instance/ppapi_ppb_instance.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_ppb_instance_x86-32.nexe"}, + "x86-64": {"url": "ppapi_ppb_instance_x86-64.nexe"}, + "arm": {"url": "ppapi_ppb_instance_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_memory/nacl.scons b/ppapi/native_client/tests/ppapi_browser/ppb_memory/nacl.scons new file mode 100644 index 0000000..4af6801 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_memory/nacl.scons @@ -0,0 +1,37 @@ +# -*- python -*- +# 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. +# +# This tests PPB_Memory_Dev. + +Import('env') + +env.Prepend(CPPDEFINES=['XP_UNIX']) + +nexe = 'ppapi_ppb_memory_%s' % env.get('TARGET_FULLARCH') +env.Alias('ppapi_ppb_memory${PROGSUFFIX}', + ['$STAGING_DIR/%s${PROGSUFFIX}' % nexe]) + +ppapi_ppb_memory_nexe = env.ComponentProgram( + nexe, + ['ppapi_ppb_memory.cc'], + EXTRA_LIBS=['${PPAPI_LIBS}', + 'ppapi_test_lib', + 'platform', # for CHECK + 'pthread', + 'gio', + ]) + +env.Publish(nexe, 'run', + ['ppapi_ppb_memory.html', + 'ppapi_ppb_memory.nmf']) + +node = env.PPAPIBrowserTester('ppapi_ppb_memory_browser_test.out', + url='ppapi_ppb_memory.html', + files=env.ExtractPublishedFiles(nexe)) + +env.AddNodeToTestSuite(node, + ['chrome_browser_tests'], + 'run_ppapi_ppb_memory_browser_test', + is_broken=env.PPAPIBrowserTesterIsBroken()) diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_memory/ppapi_ppb_memory.cc b/ppapi/native_client/tests/ppapi_browser/ppb_memory/ppapi_ppb_memory.cc new file mode 100644 index 0000000..3fcaf56 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_memory/ppapi_ppb_memory.cc @@ -0,0 +1,38 @@ +// 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 <string.h> + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/tests/ppapi_test_lib/get_browser_interface.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" + +#include "ppapi/c/pp_bool.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/dev/ppb_memory_dev.h" + +namespace { + +// Tests PPB_Memory_Dev::MemAlloc() and PPB_Core::MemFree(). +void TestMemAllocAndMemFree() { + void* mem = NULL; + mem = PPBMemoryDev()->MemAlloc(100); // No signficance to using 100 + EXPECT(mem != NULL); + memset(mem, '-', 5); + EXPECT(memcmp(mem, "-----", 5) == 0); + PPBMemoryDev()->MemFree(mem); + + TEST_PASSED; +} + +} // namespace + +void SetupTests() { + RegisterTest("TestMemAllocAndMemFree", TestMemAllocAndMemFree); +} + +void SetupPluginInterfaces() { + // none +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_memory/ppapi_ppb_memory.html b/ppapi/native_client/tests/ppapi_browser/ppb_memory/ppapi_ppb_memory.html new file mode 100644 index 0000000..bfd9a34 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_memory/ppapi_ppb_memory.html @@ -0,0 +1,66 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + <!-- Copyright (c) 2011 Google Inc. All rights reserved. --> + <head> + <meta http-equiv="Pragma" content="no-cache" /> + <meta http-equiv="Expires" content="-1" /> + <script type="text/javascript" src="nacltest.js"></script> + <script type="application/x-javascript"> + //<![CDATA[ + function setupTests(tester, plugin) { + // This function takes an array of messages and asserts that the nexe + // calls PostMessage with each of these messages, in order. + // TODO(dmichael, polina, ncbray or mball): This is copy/pasted from + // ppapi_ppb_instance.html, which was probably copy/pasted from + // somewhere else. We should move this or something like it to + // nacltest.js and remove this code from the tests that use it. + function expectMessages(test, plugin, messages) { + test.assert(messages.length > 0, 'Must provide at least one message'); + var listener = test.wrap(function(message) { + plugin.removeEventListener('message', listener, false); + test.assertEqual(message.data, messages.shift()); + if (messages.length == 0) { + test.pass(); + } else { + plugin.addEventListener('message', listener, false); + } + }); + plugin.addEventListener('message', listener, false); + } + + function addTest(test_name, responses) { + if (responses === undefined) { + responses = []; + } + var expected_messages = [test_name + ':PASSED'].concat(responses); + tester.addAsyncTest('PPB_Instance::' + test_name, function(test) { + expectMessages(test, plugin, expected_messages); + plugin.postMessage(test_name) + }); + } + + addTest('TestMemAllocAndMemFree'); + } + //]]> + </script> + <title>PPAPI PPB_Memory_Dev Test</title> + </head> + <body> + <h1>PPAPI PPB_Memory_Dev Test</h1> + + <embed type="application/x-nacl" id="test_nexe" + name="nacl_module" + src="ppapi_ppb_memory.nmf" + width="0" height="0" /> + + <script type="text/javascript"> + //<![CDATA[ + var tester = new Tester(); + setupTests(tester, $('test_nexe')); + tester.waitFor($('test_nexe')); + tester.run(); + //]]> + </script> + </body> +</html> diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_memory/ppapi_ppb_memory.nmf b/ppapi/native_client/tests/ppapi_browser/ppb_memory/ppapi_ppb_memory.nmf new file mode 100644 index 0000000..de18f8a --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_memory/ppapi_ppb_memory.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_ppb_memory_x86-32.nexe"}, + "x86-64": {"url": "ppapi_ppb_memory_x86-64.nexe"}, + "arm": {"url": "ppapi_ppb_memory_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_pdf/nacl.scons b/ppapi/native_client/tests/ppapi_browser/ppb_pdf/nacl.scons new file mode 100644 index 0000000..4643058 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_pdf/nacl.scons @@ -0,0 +1,37 @@ +# -*- python -*- +# 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. +# + +Import('env') + +env.Prepend(CPPDEFINES=['XP_UNIX']) + +nexe = 'ppapi_ppb_pdf_%s' % env.get('TARGET_FULLARCH') +env.Alias('ppapi_ppb_pdf${PROGSUFFIX}', + ['$STAGING_DIR/%s${PROGSUFFIX}' % nexe]) + +ppapi_ppb_pdf_nexe = env.ComponentProgram( + nexe, + ['ppapi_ppb_pdf.cc'], + EXTRA_LIBS=['${PPAPI_LIBS}', + 'ppapi_test_lib', + 'platform', # for CHECK + 'pthread', + 'gio', + ]) + +env.Publish(nexe, 'run', + ['ppapi_ppb_pdf.html', + 'ppapi_ppb_pdf.nmf', + 'ppapi_ppb_pdf.js']) + +node = env.PPAPIBrowserTester('ppapi_ppb_pdf_browser_test.out', + url='ppapi_ppb_pdf.html', + files=env.ExtractPublishedFiles(nexe)) + +env.AddNodeToTestSuite(node, + ['chrome_browser_tests'], + 'run_ppapi_ppb_pdf_browser_test', + is_broken=env.PPAPIBrowserTesterIsBroken()) diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_pdf/ppapi_ppb_pdf.cc b/ppapi/native_client/tests/ppapi_browser/ppb_pdf/ppapi_ppb_pdf.cc new file mode 100644 index 0000000..3347872 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_pdf/ppapi_ppb_pdf.cc @@ -0,0 +1,259 @@ +// 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 <string.h> +#include <string> + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/tests/ppapi_test_lib/get_browser_interface.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" +#include "ppapi/c/dev/ppb_font_dev.h" +#include "ppapi/c/dev/ppb_memory_dev.h" +#include "ppapi/c/pp_bool.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_rect.h" +#include "ppapi/c/ppb_core.h" +#include "ppapi/c/ppb_image_data.h" +#include "ppapi/c/ppb_var.h" +#include "ppapi/c/ppp_messaging.h" +#include "ppapi/c/private/ppb_pdf.h" + +namespace { + +const bool kCaseSensitive = true; +const bool kCaseInsensitive = false; + +const PPB_PDF* PPBPDF() { + return reinterpret_cast<const PPB_PDF*>( + GetBrowserInterface(PPB_PDF_INTERFACE)); +} + +void TestGetLocalizedString() { + // Create a vertical scrollbar. + PP_Var string = PPBPDF()->GetLocalizedString( + pp_instance(), + PP_RESOURCESTRING_PDFGETPASSWORD); + EXPECT(string.type == PP_VARTYPE_STRING); + + TEST_PASSED; +} + +void TestGetResourceImage() { + // Get an image. + PP_Resource image = PPBPDF()->GetResourceImage( + pp_instance(), + PP_RESOURCEIMAGE_PDF_BUTTON_FTP); + EXPECT(image != kInvalidResource); + EXPECT(PPBImageData()->IsImageData(image)); + + PPBCore()->ReleaseResource(image); + + return TEST_PASSED; +} + +void TestGetFontFileWithFallback() { + PP_FontDescription_Dev description; + PP_Resource font_file = PPBPDF()->GetFontFileWithFallback( + pp_instance(), + &description, + PP_PRIVATEFONTCHARSET_ANSI); + EXPECT(font_file == kInvalidResource); + + TEST_PASSED; +} + +void TestGetFontTableForPrivateFontFile() { + uint32_t output_length; + bool success = PPBPDF()->GetFontTableForPrivateFontFile( + kInvalidResource, // font + 0, // uint32_t table + NULL, // void* output + &output_length); + EXPECT(!success); + + return TEST_PASSED; +} + +typedef std::basic_string<unsigned short> Utf16String; + +Utf16String CreateWString(const std::string& string) { + Utf16String utf16String = Utf16String(); + for (std::string::const_iterator it = string.begin(); + it != string.end(); ++it) { + utf16String.push_back(static_cast<unsigned short>(*it)); + } + return utf16String; +} + +void TestSearchString() { + int count; + PP_PrivateFindResult* results; + Utf16String string = CreateWString("Hello World"); + { + Utf16String term = CreateWString("Hello"); + PPBPDF()->SearchString( + pp_instance(), + string.c_str(), + term.c_str(), + kCaseSensitive, + &results, + &count); + EXPECT(count == 1); + EXPECT(results[0].start_index == 0 && results[0].length == 5); + PPBMemoryDev()->MemFree(results); + } + { + Utf16String term = CreateWString("l"); + PPBPDF()->SearchString( + pp_instance(), + string.c_str(), + term.c_str(), + kCaseSensitive, + &results, + &count); + EXPECT(count == 3); + EXPECT(results[0].start_index == 2 && results[0].length == 1); + EXPECT(results[1].start_index == 3 && results[1].length == 1); + EXPECT(results[2].start_index == 9 && results[2].length == 1); + PPBMemoryDev()->MemFree(results); + } + { + Utf16String term = CreateWString("Hel"); + PPBPDF()->SearchString( + pp_instance(), + string.c_str(), + term.c_str(), + kCaseSensitive, + &results, + &count); + EXPECT(count == 1); + EXPECT(results[0].start_index == 0 && results[0].length == 3); + PPBMemoryDev()->MemFree(results); + } + { + Utf16String term = CreateWString("h"); + PPBPDF()->SearchString( + pp_instance(), + string.c_str(), + term.c_str(), + kCaseInsensitive, + &results, + &count); + EXPECT(count == 1); + EXPECT(results[0].start_index == 0 && results[0].length == 1); + PPBMemoryDev()->MemFree(results); + } + { + Utf16String term = CreateWString("h"); + PPBPDF()->SearchString( + pp_instance(), + string.c_str(), + term.c_str(), + kCaseSensitive, + &results, + &count); + EXPECT(count == 0); + PPBMemoryDev()->MemFree(results); + } + { + Utf16String term = CreateWString(""); + PPBPDF()->SearchString( + pp_instance(), + string.c_str(), + term.c_str(), + kCaseInsensitive, + &results, + &count); + EXPECT(count == 0); + PPBMemoryDev()->MemFree(results); + } + + TEST_PASSED; +} + +void TestDidStartLoading() { + PPBPDF()->DidStartLoading(pp_instance()); + + return TEST_PASSED; +} + +void TestDidStopLoading() { + PPBPDF()->DidStopLoading(pp_instance()); + + return TEST_PASSED; +} + +void TestSetContentRestriction() { + PPBPDF()->SetContentRestriction(pp_instance(), 0); + + return TEST_PASSED; +} + +void TestHistogramPDFPageCount() { + PPBPDF()->HistogramPDFPageCount(1); + + return TEST_PASSED; +} + +void TestUserMetricsRecordAction() { + const char* kString = "Action!"; + PP_Var action = PPBVar()->VarFromUtf8(pp_module(), + kString, + strlen(kString)); + PPBPDF()->UserMetricsRecordAction(action); + + PPBVar()->Release(action); + + return TEST_PASSED; +} + +void TestHasUnsupportedFeature() { + PPBPDF()->HasUnsupportedFeature(pp_instance()); + + return TEST_PASSED; +} + +void TestSaveAs() { + // This test pops up a file 'SaveAs' dialog, which will cause + // automated browser tests to hang. Un-comment to test manually. +/* + PPBPDF()->SaveAs(pp_instance()); +*/ + + return TEST_PASSED; +} + +} // namespace + +void SetupTests() { + RegisterTest("TestGetLocalizedString", + TestGetLocalizedString); + RegisterTest("TestGetResourceImage", + TestGetResourceImage); + RegisterTest("TestGetFontFileWithFallback", + TestGetFontFileWithFallback); + RegisterTest("TestGetFontTableForPrivateFontFile", + TestGetFontTableForPrivateFontFile); + RegisterTest("TestSearchString", + TestSearchString); + RegisterTest("TestDidStartLoading", + TestDidStartLoading); + RegisterTest("TestDidStopLoading", + TestDidStopLoading); + RegisterTest("TestSetContentRestriction", + TestSetContentRestriction); + RegisterTest("TestHistogramPDFPageCount", + TestHistogramPDFPageCount); + RegisterTest("TestUserMetricsRecordAction", + TestUserMetricsRecordAction); + RegisterTest("TestHasUnsupportedFeature", + TestHasUnsupportedFeature); + RegisterTest("TestSaveAs", + TestSaveAs); +} + +void SetupPluginInterfaces() { +} + diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_pdf/ppapi_ppb_pdf.html b/ppapi/native_client/tests/ppapi_browser/ppb_pdf/ppapi_ppb_pdf.html new file mode 100644 index 0000000..2ecb07f --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_pdf/ppapi_ppb_pdf.html @@ -0,0 +1,29 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + <!-- Copyright (c) 2011 Google Inc. All rights reserved. --> + <head> + <meta http-equiv="Pragma" content="no-cache" /> + <meta http-equiv="Expires" content="-1" /> + <script type="text/javascript" src="nacltest.js"></script> + <script type="text/javascript" src="ppapi_ppb_pdf.js"></script> + <title>PPAPI PPB_PDF_Dev Test</title> + </head> + <body> + <h1>PPAPI PPB_PDF_Dev Test</h1> + + <embed type="application/x-nacl" id="test_nexe" + name="nacl_module" + src="ppapi_ppb_pdf.nmf" + width="0" height="0" /> + + <script type="text/javascript"> + //<![CDATA[ + var tester = new Tester(); + setupTests(tester, $('test_nexe')); + tester.waitFor($('test_nexe')); + tester.run(); + //]]> + </script> + </body> +</html> diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_pdf/ppapi_ppb_pdf.js b/ppapi/native_client/tests/ppapi_browser/ppb_pdf/ppapi_ppb_pdf.js new file mode 100644 index 0000000..97b9e2d --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_pdf/ppapi_ppb_pdf.js @@ -0,0 +1,46 @@ +// 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. + +function setupTests(tester, plugin) { + // This function takes an array of messages and asserts that the nexe + // calls PostMessage with each of these messages, in order. + function expectMessages(test, plugin, messages) { + test.assert(messages.length > 0, 'Must provide at least one message'); + var listener = test.wrap(function(message) { + plugin.removeEventListener('message', listener, false); + test.assertEqual(message.data, messages.shift()); + if (messages.length == 0) { + test.pass(); + } else { + plugin.addEventListener('message', listener, false); + } + }); + plugin.addEventListener('message', listener, false); + } + + function addTest(test_name, responses) { + if (responses === undefined) { + responses = []; + } + var expected_messages = [test_name + ':PASSED']; + expected_messages.concat(responses); + tester.addAsyncTest('PPB_PDF::' + test_name, function(test) { + expectMessages(test, plugin, expected_messages); + plugin.postMessage(test_name) + }); + } + + addTest('TestGetLocalizedString'); + addTest('TestGetResourceImage'); + addTest('TestGetFontFileWithFallback'); + addTest('TestGetFontTableForPrivateFontFile'); + addTest('TestSearchString'); + addTest('TestDidStartLoading'); + addTest('TestDidStopLoading'); + addTest('TestUserMetricsRecordAction'); + addTest('TestSetContentRestriction'); + addTest('TestHistogramPDFPageCount'); + addTest('TestHasUnsupportedFeature'); + addTest('TestSaveAs'); +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_pdf/ppapi_ppb_pdf.nmf b/ppapi/native_client/tests/ppapi_browser/ppb_pdf/ppapi_ppb_pdf.nmf new file mode 100644 index 0000000..96c2636 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_pdf/ppapi_ppb_pdf.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_ppb_pdf_x86-32.nexe"}, + "x86-64": {"url": "ppapi_ppb_pdf_x86-64.nexe"}, + "arm": {"url": "ppapi_ppb_pdf_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_scrollbar/nacl.scons b/ppapi/native_client/tests/ppapi_browser/ppb_scrollbar/nacl.scons new file mode 100644 index 0000000..ca47ed1 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_scrollbar/nacl.scons @@ -0,0 +1,37 @@ +# -*- python -*- +# 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. +# + +Import('env') + +env.Prepend(CPPDEFINES=['XP_UNIX']) + +nexe = 'ppapi_ppb_scrollbar_%s' % env.get('TARGET_FULLARCH') +env.Alias('ppapi_ppb_scrollbar${PROGSUFFIX}', + ['$STAGING_DIR/%s${PROGSUFFIX}' % nexe]) + +ppapi_ppb_scrollbar_nexe = env.ComponentProgram( + nexe, + ['ppapi_ppb_scrollbar.cc'], + EXTRA_LIBS=['${PPAPI_LIBS}', + 'ppapi_test_lib', + 'platform', # for CHECK + 'pthread', + 'gio', + ]) + +env.Publish(nexe, 'run', + ['ppapi_ppb_scrollbar.html', + 'ppapi_ppb_scrollbar.nmf', + 'ppapi_ppb_scrollbar.js']) + +node = env.PPAPIBrowserTester('ppapi_ppb_scrollbar_browser_test.out', + url='ppapi_ppb_scrollbar.html', + files=env.ExtractPublishedFiles(nexe)) + +env.AddNodeToTestSuite(node, + ['chrome_browser_tests'], + 'run_ppapi_ppb_scrollbar_browser_test', + is_broken=env.PPAPIBrowserTesterIsBroken()) diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_scrollbar/ppapi_ppb_scrollbar.cc b/ppapi/native_client/tests/ppapi_browser/ppb_scrollbar/ppapi_ppb_scrollbar.cc new file mode 100644 index 0000000..ff6775b --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_scrollbar/ppapi_ppb_scrollbar.cc @@ -0,0 +1,145 @@ +// 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 <string.h> + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/tests/ppapi_test_lib/get_browser_interface.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" +#include "ppapi/c/dev/ppb_scrollbar_dev.h" +#include "ppapi/c/pp_bool.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_rect.h" +#include "ppapi/c/ppb_core.h" +#include "ppapi/c/ppb_image_data.h" +#include "ppapi/c/ppp_messaging.h" + +namespace { + +const PP_Bool kVertical = PP_TRUE; + +// Test PPB_Scrollbar_Dev::Create() and PPB_Scrollbar_Dev::IsScrollbar(). +void TestCreate() { + // Create a vertical scrollbar. + PP_Resource scrollbar = PPBScrollbarDev()->Create(pp_instance(), + kVertical); + EXPECT(scrollbar != kInvalidResource); + EXPECT(PPBScrollbarDev()->IsScrollbar(scrollbar)); + PPBCore()->ReleaseResource(scrollbar); + + // Create a horizontal scrollbar. + scrollbar = PPBScrollbarDev()->Create(pp_instance(), + PP_FALSE); // vertical + EXPECT(scrollbar != kInvalidResource); + EXPECT(PPBScrollbarDev()->IsScrollbar(scrollbar)); + PPBCore()->ReleaseResource(scrollbar); + + // Test that an invalid instance causes failure. + scrollbar = PPBScrollbarDev()->Create(kInvalidInstance, + PP_TRUE); // vertical + EXPECT(scrollbar == kInvalidResource); + EXPECT(!PPBScrollbarDev()->IsScrollbar(scrollbar)); + + TEST_PASSED; +} + +// Test PPB_Scrollbar_Dev::GetThickness(). +void TestGetThickness() { + // Thickness is a platform-defined constant; about all we can assume is + // that it is greater than 0. + PP_Resource scrollbar = PPBScrollbarDev()->Create(pp_instance(), + kVertical); + uint32_t thickness = PPBScrollbarDev()->GetThickness(scrollbar); + EXPECT(thickness > 0); + + PPBCore()->ReleaseResource(scrollbar); + + TEST_PASSED; +} + +// Test PPB_Scrollbar_Dev::GetValue(), PPB_Scrollbar_Dev::SetValue(). +void TestValue() { + // Test that initial value is 0. + PP_Resource scrollbar = PPBScrollbarDev()->Create(pp_instance(), + kVertical); + uint32_t value = PPBScrollbarDev()->GetValue(scrollbar); + EXPECT(value == 0); + + // Set document size to expand value range. + // TODO(bbudge) Refine tests once issues with scrollbar size/value are + // worked out. http://code.google.com/p/chromium/issues/detail?id=89367 + PPBScrollbarDev()->SetDocumentSize(scrollbar, 100); + PPBScrollbarDev()->SetValue(scrollbar, 10); + value = PPBScrollbarDev()->GetValue(scrollbar); + EXPECT(value == 10); + + PPBScrollbarDev()->SetValue(scrollbar, 0); + value = PPBScrollbarDev()->GetValue(scrollbar); + EXPECT(value == 0); + + PPBCore()->ReleaseResource(scrollbar); + + TEST_PASSED; +} + +// Test PPB_Scrollbar_Dev::SetDocumentSize(). This only effects scrollbar +// appearance, so it should be verified visually. +void TestSetDocumentSize() { + PP_Resource scrollbar = PPBScrollbarDev()->Create(pp_instance(), + kVertical); + PPBScrollbarDev()->SetDocumentSize(scrollbar, 100); + PPBCore()->ReleaseResource(scrollbar); + + TEST_PASSED; +} + +// Test PPB_Scrollbar_Dev::ScrollBy(). +void TestScrollBy() { + PP_Resource scrollbar = PPBScrollbarDev()->Create(pp_instance(), + kVertical); + // Set document size to expand value range. + // TODO(bbudge) Refine tests once issues with scrollbar size/value are + // worked out. http://code.google.com/p/chromium/issues/detail?id=89367 + PPBScrollbarDev()->SetDocumentSize(scrollbar, 100); + PPBScrollbarDev()->ScrollBy(scrollbar, PP_SCROLLBY_PIXEL, 10); + uint32_t value = PPBScrollbarDev()->GetValue(scrollbar); + EXPECT(value == 10); + PPBCore()->ReleaseResource(scrollbar); + + TEST_PASSED; +} + +// Test PPB_Scrollbar_Dev::SetTickMarks(). This only effects scrollbar +// appearance, so it should be verified visually. +void TestSetTickMarks() { + PP_Resource scrollbar = PPBScrollbarDev()->Create(pp_instance(), + kVertical); + uint32_t thickness = PPBScrollbarDev()->GetThickness(scrollbar); + const int32_t kCount = 2; + PP_Rect tick_marks[kCount] = { + { {0, 0}, {thickness, 1} }, + { {10, 10}, {thickness, 1} } }; + PPBScrollbarDev()->SetTickMarks(scrollbar, tick_marks, kCount); + // Make sure we can handle an empty array. + PPBScrollbarDev()->SetTickMarks(scrollbar, NULL, 0); + PPBCore()->ReleaseResource(scrollbar); + + TEST_PASSED; +} + +} // namespace + +void SetupTests() { + RegisterTest("TestCreate", TestCreate); + RegisterTest("TestGetThickness", TestGetThickness); + RegisterTest("TestValue", TestValue); + RegisterTest("TestSetDocumentSize", TestSetDocumentSize); + RegisterTest("TestSetTickMarks", TestSetTickMarks); + RegisterTest("TestScrollBy", TestScrollBy); +} + +void SetupPluginInterfaces() { +} + diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_scrollbar/ppapi_ppb_scrollbar.html b/ppapi/native_client/tests/ppapi_browser/ppb_scrollbar/ppapi_ppb_scrollbar.html new file mode 100644 index 0000000..495b238 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_scrollbar/ppapi_ppb_scrollbar.html @@ -0,0 +1,29 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + <!-- Copyright (c) 2011 Google Inc. All rights reserved. --> + <head> + <meta http-equiv="Pragma" content="no-cache" /> + <meta http-equiv="Expires" content="-1" /> + <script type="text/javascript" src="nacltest.js"></script> + <script type="text/javascript" src="ppapi_ppb_scrollbar.js"></script> + <title>PPAPI PPB_Scrollbar_Dev Test</title> + </head> + <body> + <h1>PPAPI PPB_Scrollbar_Dev Test</h1> + + <embed type="application/x-nacl" id="test_nexe" + name="nacl_module" + src="ppapi_ppb_scrollbar.nmf" + width="0" height="0" /> + + <script type="text/javascript"> + //<![CDATA[ + var tester = new Tester(); + setupTests(tester, $('test_nexe')); + tester.waitFor($('test_nexe')); + tester.run(); + //]]> + </script> + </body> +</html> diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_scrollbar/ppapi_ppb_scrollbar.js b/ppapi/native_client/tests/ppapi_browser/ppb_scrollbar/ppapi_ppb_scrollbar.js new file mode 100644 index 0000000..b9c0383 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_scrollbar/ppapi_ppb_scrollbar.js @@ -0,0 +1,40 @@ +// 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. + +function setupTests(tester, plugin) { + // This function takes an array of messages and asserts that the nexe + // calls PostMessage with each of these messages, in order. + function expectMessages(test, plugin, messages) { + test.assert(messages.length > 0, 'Must provide at least one message'); + var listener = test.wrap(function(message) { + plugin.removeEventListener('message', listener, false); + test.assertEqual(message.data, messages.shift()); + if (messages.length == 0) { + test.pass(); + } else { + plugin.addEventListener('message', listener, false); + } + }); + plugin.addEventListener('message', listener, false); + } + + function addTest(test_name, responses) { + if (responses === undefined) { + responses = []; + } + var expected_messages = [test_name + ':PASSED']; + expected_messages.concat(responses); + tester.addAsyncTest('PPB_Scrollbar::' + test_name, function(test) { + expectMessages(test, plugin, expected_messages); + plugin.postMessage(test_name) + }); + } + + addTest('TestCreate'); + addTest('TestGetThickness'); + addTest('TestValue'); + addTest('TestSetDocumentSize'); + addTest('TestSetTickMarks'); + addTest('TestScrollBy'); +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_scrollbar/ppapi_ppb_scrollbar.nmf b/ppapi/native_client/tests/ppapi_browser/ppb_scrollbar/ppapi_ppb_scrollbar.nmf new file mode 100644 index 0000000..7bbd667 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_scrollbar/ppapi_ppb_scrollbar.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_ppb_scrollbar_x86-32.nexe"}, + "x86-64": {"url": "ppapi_ppb_scrollbar_x86-64.nexe"}, + "arm": {"url": "ppapi_ppb_scrollbar_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_url_loader/build.scons b/ppapi/native_client/tests/ppapi_browser/ppb_url_loader/build.scons new file mode 100644 index 0000000..128df10 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_url_loader/build.scons @@ -0,0 +1,26 @@ +# -*- python -*- +# Copyright 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. + +# A way to build the nexe as a trusted plugin to validate directly +# against Chrome on Linux using +# --register-pepper-plugins="/path/to/libppapi_ppb_file_system.so;application/x-nacl" +# http://localhost:5103/scons-out/nacl-x86-../staging/ppapi_ppb_file_system.html + +Import('env') + +if env.Bit('linux'): + env['COMPONENT_STATIC'] = False # Build a .so, not a .a + env.Append(CFLAGS=['-std=c99']) + + sources = ['ppapi_ppb_urlloader.cc'] + + libs = ['imc', + 'gio', + 'pthread' ] + + ppapi_geturl = env.ComponentLibrary('ppapi_ppb_urlloader', + sources, + EXTRA_LIBS=libs, + no_import_lib=True) diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_url_loader/nacl.scons b/ppapi/native_client/tests/ppapi_browser/ppb_url_loader/nacl.scons new file mode 100644 index 0000000..340db24 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_url_loader/nacl.scons @@ -0,0 +1,42 @@ +# -*- python -*- +# 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. +# +# This test uses ppapi_test_lib. + +Import('env') + +env.Prepend(CPPDEFINES=['XP_UNIX']) + +nexe = 'ppapi_ppb_url_loader_%s' % env.get('TARGET_FULLARCH') +env.Alias('ppapi_ppb_url_loader${PROGSUFFIX}', + ['$STAGING_DIR/%s${PROGSUFFIX}' % nexe]) + +env.ComponentProgram(nexe, + ['ppapi_ppb_url_loader.cc'], + EXTRA_LIBS=['${PPAPI_LIBS}', + 'ppapi_test_lib', + 'platform', + 'pthread', + 'gio']) + +env.Publish(nexe, 'run', + ['ppapi_ppb_url_loader.html', + 'ppapi_ppb_url_loader.nmf', + 'ppapi_ppb_url_loader.js', + 'ppapi_ppb_url_loader.txt']) + +node = env.PPAPIBrowserTester('ppapi_ppb_url_loader_browser_test.out', + url='ppapi_ppb_url_loader.html', + files=env.ExtractPublishedFiles(nexe), + args=['--allow_404', + '--redirect_url', + '/redirect-to-existing.txt', + '/ppapi_ppb_url_loader.txt'], + browser_flags=['--enable-pepper-testing']) + +env.AddNodeToTestSuite(node, + ['chrome_browser_tests'], + 'run_ppapi_ppb_url_loader_browser_test', + is_broken=env.PPAPIBrowserTesterIsBroken()) diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_url_loader/ppapi_ppb_url_loader.cc b/ppapi/native_client/tests/ppapi_browser/ppb_url_loader/ppapi_ppb_url_loader.cc new file mode 100644 index 0000000..4f642ff --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_url_loader/ppapi_ppb_url_loader.cc @@ -0,0 +1,822 @@ +// 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 <string.h> + +#include "native_client/src/include/nacl_scoped_ptr.h" + +#include "native_client/src/shared/platform/nacl_check.h" + +#include "ppapi/c/pp_bool.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_stdint.h" +#include "ppapi/c/pp_var.h" +#include "ppapi/c/ppb_core.h" +#include "ppapi/c/ppb_file_io.h" +#include "ppapi/c/ppb_url_loader.h" +#include "ppapi/c/ppb_url_request_info.h" +#include "ppapi/c/ppb_url_response_info.h" +#include "ppapi/c/ppb_var.h" + +#include "native_client/tests/ppapi_test_lib/get_browser_interface.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" +#include "native_client/tests/ppapi_test_lib/testable_callback.h" + +namespace { + +// Same content as file kExistingURL in this directory. +const char* kContentsOfExistingURL = "Lorem ipsum dolor sit.\n"; +const char* kNonExistingURL = "does_not_exist"; +const char* kExistingURL = "ppapi_ppb_url_loader.txt"; +const char* kRedirectURL = "redirect-to-existing.txt"; +const char* kNoHeaders = NULL; + +const PP_Bool kStreamToFile = PP_TRUE; +const PP_Bool kDontStreamToFile = PP_FALSE; + +const PP_Bool kDownloadProgress = PP_TRUE; +const PP_Bool kNoDownloadProgress = PP_FALSE; + +const PP_Bool kFollowRedirects = PP_TRUE; +const PP_Bool kDontFollowRedirects = PP_FALSE; + +// Helper functions, these are candidates for being moved to a helper_lib +void CheckResponse(PP_Resource response, + int http_status, + const char* status_line, + const char* response_url, + const char* headers) { + PP_Var var; + var = PPBURLResponseInfo()->GetProperty( + response, PP_URLRESPONSEPROPERTY_STATUSCODE); + EXPECT_VAR_INT(var, http_status); + + if (status_line != NULL) { + var = PPBURLResponseInfo()->GetProperty( + response, PP_URLRESPONSEPROPERTY_STATUSLINE); + EXPECT_VAR_STRING(var, status_line); + PPBVar()->Release(var); + } + + if (response_url != NULL) { + // TODO(robertm): This needs a regexp pass to get rid of the port number + // which is non-deterministic. + var = PPBURLResponseInfo()->GetProperty( + response, PP_URLRESPONSEPROPERTY_URL); + EXPECT_VAR_STRING(var, response_url); + PPBVar()->Release(var); + } + + if (headers != NULL) { + // TODO(robertm): This needs a regexp pass to get rid of the date, etc + // which are non-deterministic. + var = PPBURLResponseInfo()->GetProperty( + response, PP_URLRESPONSEPROPERTY_HEADERS); + EXPECT_VAR_STRING(var, headers); + PPBVar()->Release(var); + } +} + + +PP_Resource MakeRequest(const char* url, + const char* method, + const char* headers, + PP_Bool to_file, + PP_Bool download_progress, + PP_Bool follow_redirects) { + PP_Resource request = PPBURLRequestInfo()->Create(pp_instance()); + EXPECT(request != kInvalidResource); + PP_Var var; + + if (url != NULL) { + var = PP_MakeString(url); + EXPECT(PP_TRUE == PPBURLRequestInfo()->SetProperty( + request, PP_URLREQUESTPROPERTY_URL, var)); + PPBVar()->Release(var); + } + + if (method != NULL) { + var = PP_MakeString(method); + EXPECT(PP_TRUE == PPBURLRequestInfo()->SetProperty( + request, PP_URLREQUESTPROPERTY_METHOD, var)); + PPBVar()->Release(var); + } + + if (headers != NULL) { + var = PP_MakeString(method); + EXPECT(PP_TRUE == PPBURLRequestInfo()->SetProperty( + request, PP_URLREQUESTPROPERTY_HEADERS, var)); + PPBVar()->Release(var); + } + + var = PP_MakeBool(to_file); + EXPECT(PP_TRUE == PPBURLRequestInfo()->SetProperty( + request, PP_URLREQUESTPROPERTY_STREAMTOFILE, var)); + + var = PP_MakeBool(download_progress); + EXPECT(PP_TRUE == PPBURLRequestInfo()->SetProperty( + request, PP_URLREQUESTPROPERTY_RECORDDOWNLOADPROGRESS, var)); + + var = PP_MakeBool(follow_redirects); + EXPECT(PP_TRUE == PPBURLRequestInfo()->SetProperty( + request, PP_URLREQUESTPROPERTY_FOLLOWREDIRECTS, var)); + return request; +} + +PP_Resource MakeDummyRequest() { + return MakeRequest(kNonExistingURL, + "GET", + kNoHeaders, + kDontStreamToFile, + kDownloadProgress, + kFollowRedirects); +} + + +int32_t ReadAndVerify(bool is_file_io, + PP_Resource resource, + int offset, + int buffer_size, + const nacl::string& expected) { + nacl::scoped_array<char> buffer(new char[buffer_size]); + TestableCallback callback(pp_instance(), true); + nacl::string actual; + int32_t rv; + for (;;) { + callback.Reset(); + if (is_file_io) { + rv = PPBFileIO()->Read(resource, + offset + actual.size(), + buffer.get(), + buffer_size, + callback.GetCallback()); + } else { + rv = PPBURLLoader()->ReadResponseBody( + resource, buffer.get(), buffer_size, callback.GetCallback()); + } + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + if (rv == 0) { + break; + } else if (rv < 0) { + return rv; + } else { + actual.append(buffer.get(), rv); + } + } + + // rv was zero + EXPECT(actual == expected); + return 0; +} + + +int32_t ReadAndVerifyResponseBody(PP_Resource loader, + int buffer_size, + const nacl::string& expected) { + return ReadAndVerify(false, loader, 0, buffer_size, expected); +} + + +int32_t ReadAndVerifyFileContents(PP_Resource file_io, + int offset, + int buffer_size, + const nacl::string& expected) { + return ReadAndVerify(true, file_io, offset, buffer_size, expected); +} + + +void TestOpenSuccess() { + int32_t rv; + TestableCallback callback(pp_instance(), true); + PP_Resource loader; + PP_Resource response; + PP_Resource request = MakeRequest(kExistingURL, "GET", kNoHeaders, + kDontStreamToFile, + kDownloadProgress, + kFollowRedirects); + + LOG_TO_BROWSER("open and read entire existing file (all at once)"); + callback.Reset(); + loader = PPBURLLoader()->Create(pp_instance()); + rv = PPBURLLoader()->Open(loader, request, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_OK == rv); + response = PPBURLLoader()->GetResponseInfo(loader); + CheckResponse(response, 200, "OK", NULL, NULL); + ReadAndVerifyResponseBody(loader, 1024, kContentsOfExistingURL); + PPBCore()->ReleaseResource(loader); + + LOG_TO_BROWSER("open and read entire existing file (one byte at a time)"); + callback.Reset(); + loader = PPBURLLoader()->Create(pp_instance()); + rv = PPBURLLoader()->Open(loader, request, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_OK == rv); + response = PPBURLLoader()->GetResponseInfo(loader); + CheckResponse(response, 200, "OK", NULL, NULL); + ReadAndVerifyResponseBody(loader, 1, kContentsOfExistingURL); + PPBCore()->ReleaseResource(loader); + + PPBCore()->ReleaseResource(request); + + TEST_PASSED; +} + + +void TestOpenRedirect() { + int32_t rv; + TestableCallback callback(pp_instance(), true); + PP_Resource loader; + PP_Resource response; + PP_Resource request_no_redirect = MakeRequest(kRedirectURL, "GET", kNoHeaders, + kDontStreamToFile, + kDownloadProgress, + kDontFollowRedirects); + PP_Resource request_redirect = MakeRequest(kRedirectURL, "GET", kNoHeaders, + kDontStreamToFile, + kDownloadProgress, + kFollowRedirects); + + LOG_TO_BROWSER("redirect do NOT follow"); + callback.Reset(); + loader = PPBURLLoader()->Create(pp_instance()); + rv = PPBURLLoader()->Open( + loader, request_no_redirect, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_OK == rv); + response = PPBURLLoader()->GetResponseInfo(loader); + CheckResponse(response, 301, "Moved", NULL, NULL); + PPBCore()->ReleaseResource(loader); + + LOG_TO_BROWSER("redirect follow"); + callback.Reset(); + loader = PPBURLLoader()->Create(pp_instance()); + rv = PPBURLLoader()->Open(loader, request_redirect, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_OK == rv); + response = PPBURLLoader()->GetResponseInfo(loader); + CheckResponse(response, 200, "OK", NULL, NULL); + // TODO(robertm): also try smaller sizes, e.g. one and zero + EXPECT(PP_OK == + ReadAndVerifyResponseBody(loader, 1024, kContentsOfExistingURL)); + + PPBCore()->ReleaseResource(loader); + PPBCore()->ReleaseResource(request_redirect); + PPBCore()->ReleaseResource(request_no_redirect); + + TEST_PASSED; +} + + +void TestOpenFailure() { + int32_t rv; + TestableCallback callback(pp_instance(), true); + PP_Resource request = MakeDummyRequest(); + PP_Resource loader = PPBURLLoader()->Create(pp_instance()); + + LOG_TO_BROWSER("open with non existing url"); + callback.Reset(); + rv = PPBURLLoader()->Open(loader, request, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_OK == rv); + + PP_Resource response = PPBURLLoader()->GetResponseInfo(loader); + CheckResponse(response, 404, "File not found", NULL, NULL); + + PPBCore()->ReleaseResource(request); + PPBCore()->ReleaseResource(loader); + + TEST_PASSED; +} + + +void TestStreamToFile() { + int32_t rv; + TestableCallback callback(pp_instance(), true); + PP_Resource loader; + PP_Resource file_ref; + PP_Resource response; + PP_Resource file_io; + PP_Resource request = MakeRequest(kExistingURL, "GET", kNoHeaders, + kStreamToFile, + kDownloadProgress, + kFollowRedirects); + + callback.Reset(); + loader = PPBURLLoader()->Create(pp_instance()); + rv = PPBURLLoader()->Open(loader, request, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_OK == rv); + + response = PPBURLLoader()->GetResponseInfo(loader); + CheckResponse(response, 200, "OK", NULL, NULL); + + file_ref = PPBURLResponseInfo()->GetBodyAsFileRef(response); + callback.Reset(); + rv = PPBURLLoader()->FinishStreamingToFile(loader, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_OK == rv); + + callback.Reset(); + file_io = PPBFileIO()->Create(pp_instance()); + rv = PPBFileIO()->Open( + file_io, file_ref, PP_FILEOPENFLAG_READ, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_OK == rv); + + // TODO(robertm): add tests with different buffer sizes + ReadAndVerifyFileContents(file_io, 0, 1024, kContentsOfExistingURL); + + PPBCore()->ReleaseResource(file_io); + PPBCore()->ReleaseResource(file_ref); + PPBCore()->ReleaseResource(response); + PPBCore()->ReleaseResource(loader); + PPBCore()->ReleaseResource(request); + + TEST_PASSED; +} + + +void TestOpenSimple() { + int32_t rv; + TestableCallback callback(pp_instance(), true); + PP_Resource request = MakeDummyRequest(); + PP_Resource loader; + + LOG_TO_BROWSER("open with loader/request invalid"); + callback.Reset(); + rv = PPBURLLoader()->Open( + kInvalidResource, kInvalidResource, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_ERROR_BADRESOURCE == rv); + callback.Reset(); + rv = PPBURLLoader()->Open( + kNotAResource, kNotAResource, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_ERROR_BADRESOURCE == rv); + + LOG_TO_BROWSER("open with loader invalid"); + callback.Reset(); + rv = PPBURLLoader()->Open(kInvalidResource, request, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_ERROR_BADRESOURCE == rv); + callback.Reset(); + rv = PPBURLLoader()->Open(kNotAResource, request, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_ERROR_BADRESOURCE == rv); + callback.Reset(); + rv = PPBURLLoader()->Open(request, request, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_ERROR_BADRESOURCE == rv); + + LOG_TO_BROWSER("open with request invalid"); + loader = PPBURLLoader()->Create(pp_instance()); + callback.Reset(); + rv = PPBURLLoader()->Open(loader, kInvalidResource, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_ERROR_BADARGUMENT == rv); + callback.Reset(); + rv = PPBURLLoader()->Open(loader, kNotAResource, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_ERROR_BADARGUMENT == rv); + callback.Reset(); + rv = PPBURLLoader()->Open(loader, loader, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_ERROR_BADARGUMENT == rv); + PPBCore()->ReleaseResource(loader); + + LOG_TO_BROWSER("open (synchronous) with blocking callback on main thread"); + loader = PPBURLLoader()->Create(pp_instance()); + // We are on the main thread, performing a sync call should fail + rv = PPBURLLoader()->Open(loader, request, PP_BlockUntilComplete()); + EXPECT(PP_ERROR_BADARGUMENT == rv); + PPBCore()->ReleaseResource(loader); + + LOG_TO_BROWSER("open (asynchronous) normal"); + loader = PPBURLLoader()->Create(pp_instance()); + callback.Reset(); + rv = PPBURLLoader()->Open(loader, request, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_OK == rv); + PPBCore()->ReleaseResource(loader); + + LOG_TO_BROWSER("open with with released loader"); + loader = PPBURLLoader()->Create(pp_instance()); + PPBCore()->ReleaseResource(loader); + callback.Reset(); + rv = PPBURLLoader()->Open(loader, request, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_ERROR_BADRESOURCE == rv); + + PPBCore()->ReleaseResource(request); + + TEST_PASSED; +} + + +void TestDoubleOpen() { + int32_t rv; + PP_Resource loader; + TestableCallback callback(pp_instance(), true); + PP_Resource request1 = MakeRequest(kExistingURL, "GET", kNoHeaders, + kDontStreamToFile, + kDownloadProgress, + kDontFollowRedirects); + PP_Resource request2 = MakeRequest(kNonExistingURL, "GET", kNoHeaders, + kDontStreamToFile, + kDownloadProgress, + kDontFollowRedirects); + + LOG_TO_BROWSER("open two requests on the same loader without Close"); + loader = PPBURLLoader()->Create(pp_instance()); + callback.Reset(); + rv = PPBURLLoader()->Open(loader, request1, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_OK == rv); + + callback.Reset(); + rv = PPBURLLoader()->Open(loader, request2, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_ERROR_INPROGRESS == rv); + PPBCore()->ReleaseResource(loader); + + LOG_TO_BROWSER("open two requests on the same loader with Close"); + // NOTE: using Close should NOT make a difference either + loader = PPBURLLoader()->Create(pp_instance()); + callback.Reset(); + rv = PPBURLLoader()->Open(loader, request1, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_OK == rv); + + PPBURLLoader()->Close(loader); + + callback.Reset(); + rv = PPBURLLoader()->Open(loader, request2, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_ERROR_INPROGRESS == rv); + PPBCore()->ReleaseResource(loader); + + PPBCore()->ReleaseResource(request1); + PPBCore()->ReleaseResource(request2); + + TEST_PASSED; +} + + +void TestProgressSimple() { + int32_t rv; + int64_t received; + int64_t total; + TestableCallback callback(pp_instance(), true); + PP_Resource loader; + PP_Resource req_bad = MakeDummyRequest(); + PP_Resource req_good = MakeRequest(kExistingURL, "GET", kNoHeaders, + kDontStreamToFile, + kDownloadProgress, + kDontFollowRedirects); + PP_Resource req_good_no_progress = MakeRequest(kExistingURL, + "GET", + kNoHeaders, + kDontStreamToFile, + kNoDownloadProgress, + kDontFollowRedirects); + + LOG_TO_BROWSER("progress on invalid loader"); + rv = PPBURLLoader()->GetDownloadProgress(kInvalidResource, &received, &total); + EXPECT(PP_FALSE == rv); + rv = PPBURLLoader()->GetDownloadProgress(kNotAResource, &received, &total); + EXPECT(PP_FALSE == rv); + rv = PPBURLLoader()->GetDownloadProgress(req_bad, &received, &total); + EXPECT(PP_FALSE == rv); + + LOG_TO_BROWSER("progress for failed request"); + callback.Reset(); + loader = PPBURLLoader()->Create(pp_instance()); + rv = PPBURLLoader()->Open(loader, req_bad, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_OK == rv); + rv = PPBURLLoader()->GetDownloadProgress(loader, &received, &total); + EXPECT(PP_TRUE == rv); + PPBCore()->ReleaseResource(loader); + + LOG_TO_BROWSER("progress for request"); + callback.Reset(); + loader = PPBURLLoader()->Create(pp_instance()); + rv = PPBURLLoader()->Open(loader, req_good, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_OK == rv); + rv = PPBURLLoader()->GetDownloadProgress(loader, &received, &total); + EXPECT(PP_TRUE == rv); + const int num_bytes_expected = strlen(kContentsOfExistingURL); + EXPECT(total == num_bytes_expected); + ReadAndVerifyResponseBody(loader, 1024, kContentsOfExistingURL); + rv = PPBURLLoader()->GetDownloadProgress(loader, &received, &total); + EXPECT(PP_TRUE == rv); + EXPECT(total == num_bytes_expected); + EXPECT(received == num_bytes_expected); + + PPBCore()->ReleaseResource(loader); + + LOG_TO_BROWSER("progress for request 'without progress'"); + callback.Reset(); + loader = PPBURLLoader()->Create(pp_instance()); + rv = PPBURLLoader()->Open( + loader, req_good_no_progress, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_OK == rv); + rv = PPBURLLoader()->GetDownloadProgress(loader, &received, &total); + EXPECT(PP_FALSE == rv); + PPBCore()->ReleaseResource(loader); + + PPBCore()->ReleaseResource(req_bad); + PPBCore()->ReleaseResource(req_good); + PPBCore()->ReleaseResource(req_good_no_progress); + + TEST_PASSED; +} + + +void TestResponseInfoSimple() { + PP_Resource response; + PP_Resource request = MakeDummyRequest(); + + LOG_TO_BROWSER("response info on invalid loader"); + response = PPBURLLoader()->GetResponseInfo(kInvalidResource); + EXPECT(kInvalidResource == response); + response = PPBURLLoader()->GetResponseInfo(kNotAResource); + EXPECT(kInvalidResource == response); + response = PPBURLLoader()->GetResponseInfo(request); + EXPECT(kInvalidResource == response); + + LOG_TO_BROWSER("response info without open"); + PP_Resource loader = PPBURLLoader()->Create(pp_instance()); + response = PPBURLLoader()->GetResponseInfo(loader); + EXPECT(kInvalidResource == response); + PPBCore()->ReleaseResource(loader); + + PPBCore()->ReleaseResource(request); + + TEST_PASSED; +} + + +void TestCloseSimple() { + PP_Resource request = MakeDummyRequest(); + LOG_TO_BROWSER("close on invalid loader"); + // we just make sure we do not crash here. + PPBURLLoader()->Close(kInvalidResource); + PPBURLLoader()->Close(kNotAResource); + PPBURLLoader()->Close(request); + + PPBCore()->ReleaseResource(request); + + TEST_PASSED; +} + + +void TestReadSimple() { + int32_t rv; + char buffer[1024]; + PP_Resource loader; + TestableCallback callback(pp_instance(), true); + + PP_Resource request = MakeDummyRequest(); + + LOG_TO_BROWSER("read on invalid loader"); + callback.Reset(); + rv = PPBURLLoader()->ReadResponseBody( + kInvalidResource, buffer, sizeof buffer, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_ERROR_BADRESOURCE == rv); + + callback.Reset(); + rv = PPBURLLoader()->ReadResponseBody( + kNotAResource, buffer, sizeof buffer, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_ERROR_BADRESOURCE == rv); + + callback.Reset(); + rv = PPBURLLoader()->ReadResponseBody( + request, buffer, sizeof buffer, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_ERROR_BADRESOURCE == rv); + + LOG_TO_BROWSER("read without open"); + loader = PPBURLLoader()->Create(pp_instance()); + callback.Reset(); + rv = PPBURLLoader()->ReadResponseBody( + loader, buffer, sizeof buffer, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_ERROR_FAILED == rv); + PPBCore()->ReleaseResource(loader); + + PPBCore()->ReleaseResource(request); + + TEST_PASSED; +} + + +void TestStreamToFileSimple() { + int32_t rv; + PP_Resource loader; + TestableCallback callback(pp_instance(), true); + PP_Resource request = MakeDummyRequest(); + + LOG_TO_BROWSER("stream on invalid loader"); + callback.Reset(); + rv = PPBURLLoader()->FinishStreamingToFile( + kInvalidResource, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_ERROR_BADRESOURCE == rv); + + callback.Reset(); + rv = PPBURLLoader()->FinishStreamingToFile( + kNotAResource, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_ERROR_BADRESOURCE == rv); + + callback.Reset(); + rv = PPBURLLoader()->FinishStreamingToFile( + request, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_ERROR_BADRESOURCE == rv); + + LOG_TO_BROWSER("stream without open"); + callback.Reset(); + loader = PPBURLLoader()->Create(pp_instance()); + rv = PPBURLLoader()->FinishStreamingToFile( + loader, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_ERROR_FAILED == rv); + PPBCore()->ReleaseResource(loader); + + PPBCore()->ReleaseResource(request); + + TEST_PASSED; +} + + +void TestAbort() { + int32_t rv; + PP_Resource loader; + PP_Resource request = MakeRequest(kExistingURL, "GET", kNoHeaders, + kDontStreamToFile, + kDownloadProgress, + kDontFollowRedirects); + TestableCallback callback(pp_instance(), true); + + LOG_TO_BROWSER("release loader while open in flight"); + loader = PPBURLLoader()->Create(pp_instance()); + callback.Reset(); + rv = PPBURLLoader()->Open(loader, request, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + PPBCore()->ReleaseResource(loader); + rv = callback.WaitForResult(); + EXPECT(PP_ERROR_ABORTED == rv); + PPBCore()->ReleaseResource(loader); + + // TODO(sanga,polina): Investigate why this case is hanging + // The problem is that the callback never gets called. + // So WaitForResult() never returns. + // This is also true for regular callback. +#if 0 + LOG_TO_BROWSER("close loader while open in flight"); + loader = PPBURLLoader()->Create(pp_instance()); + callback.Reset(); + rv = PPBURLLoader()->Open(loader, request, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + PPBURLLoader()->Close(loader); + rv = callback.WaitForResult(); + EXPECT(PP_ERROR_ABORTED == rv); + PPBCore()->ReleaseResource(loader); +#endif + + // NOTE: this should be last in this function since it releases the request + LOG_TO_BROWSER("release request while open in flight"); + loader = PPBURLLoader()->Create(pp_instance()); + callback.Reset(); + rv = PPBURLLoader()->Open(loader, request, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + PPBCore()->ReleaseResource(request); + rv = callback.WaitForResult(); + // loader holds another ref so this is ok + EXPECT(PP_OK == rv); + PPBCore()->ReleaseResource(loader); + + TEST_PASSED; +} + + +void TestOpenReadMismatch() { + int32_t rv; + char buffer[1024]; + TestableCallback callback(pp_instance(), true); + PP_Resource loader; + PP_Resource response; + PP_Resource request_regular = MakeRequest(kExistingURL, "GET", kNoHeaders, + kDontStreamToFile, + kDownloadProgress, + kFollowRedirects); + PP_Resource request_stream = MakeRequest(kExistingURL, "GET", kNoHeaders, + kStreamToFile, + kDownloadProgress, + kFollowRedirects); + + LOG_TO_BROWSER("open regularly but try streaming"); + callback.Reset(); + loader = PPBURLLoader()->Create(pp_instance()); + rv = PPBURLLoader()->Open(loader, request_regular, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_OK == rv); + response = PPBURLLoader()->GetResponseInfo(loader); + CheckResponse(response, 200, "OK", NULL, NULL); + PP_Resource file_ref = PPBURLResponseInfo()->GetBodyAsFileRef(response); + EXPECT(kInvalidResource == file_ref); + PPBCore()->ReleaseResource(loader); + + LOG_TO_BROWSER("open as stream but read via ReadResponseBody"); + callback.Reset(); + loader = PPBURLLoader()->Create(pp_instance()); + rv = PPBURLLoader()->Open(loader, request_stream, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_OK == rv); + response = PPBURLLoader()->GetResponseInfo(loader); + CheckResponse(response, 200, "OK", NULL, NULL); + rv = PPBURLLoader()->ReadResponseBody( + loader, buffer, sizeof buffer, callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == rv); + rv = callback.WaitForResult(); + EXPECT(PP_ERROR_FAILED == rv); + PPBCore()->ReleaseResource(loader); + + PPBCore()->ReleaseResource(request_stream); + PPBCore()->ReleaseResource(request_regular); + + TEST_PASSED; +} + +} // namespace + + +void SetupTests() { + // This test requires PPBTestingDev() + CHECK(PPBTestingDev() != NULL); + + // TODO(robertm): add POST tests + RegisterTest("TestOpenSimple", TestOpenSimple); + RegisterTest("TestStreamToFileSimple", TestStreamToFileSimple); + RegisterTest("TestProgressSimple", TestProgressSimple); + RegisterTest("TestResponseInfoSimple", TestResponseInfoSimple); + RegisterTest("TestCloseSimple", TestCloseSimple); + RegisterTest("TestReadSimple", TestReadSimple); + + RegisterTest("TestAbort", TestAbort); + RegisterTest("TestDoubleOpen", TestDoubleOpen); + RegisterTest("TestOpenSuccess", TestOpenSuccess); + RegisterTest("TestOpenFailure", TestOpenFailure); + RegisterTest("TestOpenRedirect", TestOpenRedirect); + RegisterTest("TestOpenReadMismatch", TestOpenReadMismatch); + RegisterTest("TestStreamToFile", TestStreamToFile); +} + + +void SetupPluginInterfaces() { + // No PPP interface to test. +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_url_loader/ppapi_ppb_url_loader.html b/ppapi/native_client/tests/ppapi_browser/ppb_url_loader/ppapi_ppb_url_loader.html new file mode 100644 index 0000000..04a229e --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_url_loader/ppapi_ppb_url_loader.html @@ -0,0 +1,29 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + <!-- Copyright 2011 Google Inc. All rights reserved. --> + <head> + <META HTTP-EQUIV="Pragma" CONTENT="no-cache" /> + <META HTTP-EQUIV="Expires" CONTENT="-1" /> + <script type="text/javascript" src="nacltest.js"></script> + <script type="text/javascript" src="ppapi_ppb_url_loader.js"></script> + <title>PPAPI PPB_UrlLoader Test</title> + </head> + <body> + <h1>PPAPI PPB_UrlLoader Test</h1> + + <embed type="application/x-nacl" id="test_nexe" + name="nacl_module" + src="ppapi_ppb_url_loader.nmf" + width="0" height="0" /> + + <script type="text/javascript"> + //<![CDATA[ + var tester = new Tester(); + setupTests(tester, $('test_nexe')); + tester.waitFor($('test_nexe')); + tester.run(); + //]]> + </script> + </body> +</html> diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_url_loader/ppapi_ppb_url_loader.js b/ppapi/native_client/tests/ppapi_browser/ppb_url_loader/ppapi_ppb_url_loader.js new file mode 100644 index 0000000..f936d63 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_url_loader/ppapi_ppb_url_loader.js @@ -0,0 +1,36 @@ +// 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. + +function setupTests(tester, plugin) { + var kTests = ['TestStreamToFileSimple', + 'TestProgressSimple', + 'TestOpenSimple', + 'TestResponseInfoSimple', + 'TestCloseSimple', + 'TestReadSimple', + + 'TestOpenReadMismatch', + 'TestAbort', + 'TestDoubleOpen', + 'TestOpenSuccess', + 'TestOpenRedirect', + 'TestOpenFailure', + 'TestStreamToFile', + ]; + + + for (var i = 0; i < kTests.length; i++) { + var name = kTests[i]; + + // NOTE: closure semantics in JS will always use the + // last value of "name". + var f = function(n) { + return function(test) { + test.expectMessageSequence(plugin, [n +':PASSED']); + plugin.postMessage(n); + }} (name); + + tester.addAsyncTest(name, f); + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_url_loader/ppapi_ppb_url_loader.nmf b/ppapi/native_client/tests/ppapi_browser/ppb_url_loader/ppapi_ppb_url_loader.nmf new file mode 100644 index 0000000..1a42c09 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_url_loader/ppapi_ppb_url_loader.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": { "url": "ppapi_ppb_url_loader_x86-32.nexe" }, + "x86-64": { "url": "ppapi_ppb_url_loader_x86-64.nexe" }, + "arm": { "url": "ppapi_ppb_url_loader_arm.nexe" } + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_url_loader/ppapi_ppb_url_loader.txt b/ppapi/native_client/tests/ppapi_browser/ppb_url_loader/ppapi_ppb_url_loader.txt new file mode 100644 index 0000000..1cca58b --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_url_loader/ppapi_ppb_url_loader.txt @@ -0,0 +1 @@ +Lorem ipsum dolor sit. diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_url_request_info/nacl.scons b/ppapi/native_client/tests/ppapi_browser/ppb_url_request_info/nacl.scons new file mode 100644 index 0000000..8f78e4b --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_url_request_info/nacl.scons @@ -0,0 +1,39 @@ +# -*- python -*- +# 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. +# +# This test uses ppapi_test_lib. + +Import('env') + +env.Prepend(CPPDEFINES=['XP_UNIX']) + +nexe = 'ppapi_ppb_url_request_info_%s' % env.get('TARGET_FULLARCH') +env.Alias('ppapi_ppb_url_request_info${PROGSUFFIX}', + [ '$STAGING_DIR/%s${PROGSUFFIX}' % nexe ]) + +ppapi_ppb_url_request_info_nexe = env.ComponentProgram( + nexe, + [ 'ppapi_ppb_url_request_info.cc' ], + EXTRA_LIBS=['${PPAPI_LIBS}', + 'ppapi_test_lib', + 'platform', # for CHECK + 'pthread', + 'gio', + ]) + +env.Publish(nexe, 'run', + ['ppapi_ppb_url_request_info.html', + 'ppapi_ppb_url_request_info.nmf', + 'ppapi_ppb_url_request_info.js']) + +node = env.PPAPIBrowserTester('ppapi_ppb_url_request_info_browser_test.out', + url='ppapi_ppb_url_request_info.html', + files=env.ExtractPublishedFiles(nexe), + browser_flags=['--enable-pepper-testing']) + +env.AddNodeToTestSuite(node, + ['chrome_browser_tests'], + 'run_ppapi_ppb_url_request_info_browser_test', + is_broken=env.PPAPIBrowserTesterIsBroken()) diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_url_request_info/ppapi_ppb_url_request_info.cc b/ppapi/native_client/tests/ppapi_browser/ppb_url_request_info/ppapi_ppb_url_request_info.cc new file mode 100644 index 0000000..736d9c0 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_url_request_info/ppapi_ppb_url_request_info.cc @@ -0,0 +1,494 @@ +// 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. + +// Tests PPB_URLRequestInfo. + +#include <string.h> + +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/tests/ppapi_test_lib/get_browser_interface.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" +#include "native_client/tests/ppapi_test_lib/testable_callback.h" + +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/ppb_core.h" +#include "ppapi/c/ppb_file_io.h" +#include "ppapi/c/ppb_file_ref.h" +#include "ppapi/c/ppb_file_system.h" +#include "ppapi/c/ppb_url_loader.h" +#include "ppapi/c/ppb_url_request_info.h" +#include "ppapi/c/ppb_url_response_info.h" +#include "ppapi/c/ppb_var.h" + +namespace { + +// Tests +// PP_Resource Create(PP_Instance instance). +void TestCreate() { + PP_Resource url_request = kInvalidResource; + + // Invalid instance -> invalid resource. + url_request = PPBURLRequestInfo()->Create(kInvalidInstance); + EXPECT(url_request == kInvalidResource); + + // Valid instance -> valid resource. + url_request = PPBURLRequestInfo()->Create(pp_instance()); + EXPECT(url_request != kInvalidResource); + + PPBCore()->ReleaseResource(url_request); + TEST_PASSED; +} + +// Tests +// PP_Bool IsURLRequestInfo(PP_Resource resource). +void TestIsURLRequestInfo() { + const PPB_URLRequestInfo* ppb = PPBURLRequestInfo(); + + // Invalid / non-existent / non-URLRequestInfo resource -> false. + EXPECT(PP_FALSE == ppb->IsURLRequestInfo(kInvalidResource)); + EXPECT(PP_FALSE == ppb->IsURLRequestInfo(kNotAResource)); + PP_Resource url_loader = PPBURLLoader()->Create(pp_instance()); + EXPECT(url_loader != kInvalidResource); + EXPECT(PP_FALSE == ppb->IsURLRequestInfo(url_loader)); + PPBCore()->ReleaseResource(url_loader); + + // Current URLRequestInfo resource -> true. + PP_Resource url_request = ppb->Create(pp_instance()); + EXPECT(PP_TRUE == ppb->IsURLRequestInfo(url_request)); + + // Released URLRequestInfo resource -> false. + PPBCore()->ReleaseResource(url_request); + EXPECT(PP_FALSE == ppb->IsURLRequestInfo(url_request)); + + TEST_PASSED; +} + +// Tests +// PP_Bool SetProperty(PP_Resource request, +// PP_URLRequestProperty property, +// struct PP_Var value); +void TestSetProperty() { + struct PropertyTestData { + PropertyTestData(PP_URLRequestProperty _property, + const std::string& _property_name, + PP_Var _var, PP_Bool _expected_value) : + property(_property), property_name(_property_name), + var(_var), expected_value(_expected_value) { + PPBVar()->AddRef(var); + } + PP_URLRequestProperty property; + std::string property_name; + PP_Var var; + PP_Bool expected_value; + }; + + // All bool properties should accept PP_TRUE and PP_FALSE, while rejecting + // all other variable types. + #define ADD_BOOL_PROPERTY(_prop_name) \ + PropertyTestData(ID_STR(_prop_name), PP_MakeBool(PP_TRUE), PP_TRUE), \ + PropertyTestData(ID_STR(_prop_name), PP_MakeBool(PP_FALSE), PP_TRUE), \ + PropertyTestData(ID_STR(_prop_name), PP_MakeUndefined(), PP_FALSE), \ + PropertyTestData(ID_STR(_prop_name), PP_MakeNull(), PP_FALSE), \ + PropertyTestData(ID_STR(_prop_name), PP_MakeInt32(0), PP_FALSE), \ + PropertyTestData(ID_STR(_prop_name), PP_MakeDouble(0.0), PP_FALSE) + + // These property types are always invalid for string properties. + #define ADD_STRING_INVALID_PROPERTIES(_prop_name) \ + PropertyTestData(ID_STR(_prop_name), PP_MakeNull(), PP_FALSE), \ + PropertyTestData(ID_STR(_prop_name), PP_MakeBool(PP_FALSE), PP_FALSE), \ + PropertyTestData(ID_STR(_prop_name), PP_MakeInt32(0), PP_FALSE), \ + PropertyTestData(ID_STR(_prop_name), PP_MakeDouble(0.0), PP_FALSE) + + #define ADD_INT_INVALID_PROPERTIES(_prop_name) \ + PropertyTestData(ID_STR(_prop_name), PP_MakeUndefined(), PP_FALSE), \ + PropertyTestData(ID_STR(_prop_name), PP_MakeNull(), PP_FALSE), \ + PropertyTestData(ID_STR(_prop_name), PP_MakeBool(PP_FALSE), PP_FALSE), \ + PropertyTestData(ID_STR(_prop_name), PP_MakeString(""), PP_FALSE), \ + PropertyTestData(ID_STR(_prop_name), PP_MakeDouble(0.0), PP_FALSE) + + #define ID_STR(arg) arg, #arg + PropertyTestData test_data[] = { + ADD_BOOL_PROPERTY(PP_URLREQUESTPROPERTY_STREAMTOFILE), + ADD_BOOL_PROPERTY(PP_URLREQUESTPROPERTY_FOLLOWREDIRECTS), + ADD_BOOL_PROPERTY(PP_URLREQUESTPROPERTY_RECORDDOWNLOADPROGRESS), + ADD_BOOL_PROPERTY(PP_URLREQUESTPROPERTY_RECORDUPLOADPROGRESS), + ADD_BOOL_PROPERTY(PP_URLREQUESTPROPERTY_ALLOWCROSSORIGINREQUESTS), + ADD_BOOL_PROPERTY(PP_URLREQUESTPROPERTY_ALLOWCREDENTIALS), + ADD_STRING_INVALID_PROPERTIES(PP_URLREQUESTPROPERTY_URL), + ADD_STRING_INVALID_PROPERTIES(PP_URLREQUESTPROPERTY_METHOD), + ADD_STRING_INVALID_PROPERTIES(PP_URLREQUESTPROPERTY_HEADERS), + ADD_STRING_INVALID_PROPERTIES( + PP_URLREQUESTPROPERTY_CUSTOMREFERRERURL), + ADD_STRING_INVALID_PROPERTIES( + PP_URLREQUESTPROPERTY_CUSTOMCONTENTTRANSFERENCODING), + ADD_INT_INVALID_PROPERTIES( + PP_URLREQUESTPROPERTY_PREFETCHBUFFERUPPERTHRESHOLD), + ADD_INT_INVALID_PROPERTIES( + PP_URLREQUESTPROPERTY_PREFETCHBUFFERLOWERTHRESHOLD), + PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_URL), + PP_MakeString("http://www.google.com"), PP_TRUE), + PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_URL), + PP_MakeString("foo.jpg"), PP_TRUE), + PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_METHOD), + PP_MakeString("GET"), PP_TRUE), + PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_METHOD), + PP_MakeString("POST"), PP_TRUE), + PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_HEADERS), + PP_MakeString("Accept: text/plain"), PP_TRUE), + PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_HEADERS), + PP_MakeString(""), PP_TRUE), + PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_CUSTOMREFERRERURL), + PP_MakeString("http://www.google.com"), PP_TRUE), + PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_CUSTOMREFERRERURL), + PP_MakeString(""), PP_TRUE), + PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_CUSTOMREFERRERURL), + PP_MakeUndefined(), PP_TRUE), + PropertyTestData( + ID_STR(PP_URLREQUESTPROPERTY_CUSTOMCONTENTTRANSFERENCODING), + PP_MakeString("base64"), PP_TRUE), + PropertyTestData( + ID_STR(PP_URLREQUESTPROPERTY_CUSTOMCONTENTTRANSFERENCODING), + PP_MakeString(""), PP_TRUE), + PropertyTestData( + ID_STR(PP_URLREQUESTPROPERTY_CUSTOMCONTENTTRANSFERENCODING), + PP_MakeUndefined(), PP_TRUE), + PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_URL), + PP_MakeUndefined(), PP_FALSE), + PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_METHOD), + PP_MakeUndefined(), PP_FALSE), + PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_HEADERS), + PP_MakeString("Proxy-Authorization: Basic dXNlcjpwYXNzd29yZA=="), + PP_FALSE), + PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_HEADERS), + PP_MakeString("Accept-Encoding: *\n" + "Accept-Charset: iso-8859-5, unicode-1-1;q=0.8"), + PP_FALSE), + PropertyTestData( + ID_STR(PP_URLREQUESTPROPERTY_PREFETCHBUFFERUPPERTHRESHOLD), + PP_MakeInt32(0), PP_TRUE), + PropertyTestData( + ID_STR(PP_URLREQUESTPROPERTY_PREFETCHBUFFERUPPERTHRESHOLD), + PP_MakeInt32(100), PP_TRUE), + PropertyTestData( + ID_STR(PP_URLREQUESTPROPERTY_PREFETCHBUFFERLOWERTHRESHOLD), + PP_MakeInt32(0), PP_TRUE), + PropertyTestData( + ID_STR(PP_URLREQUESTPROPERTY_PREFETCHBUFFERLOWERTHRESHOLD), + PP_MakeInt32(100), PP_TRUE), + // Bug filed against Chrome to validate SetProperty values better. + // http://code.google.com/p/chromium/issues/detail?id=89842. + /* + PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_URL), + PP_MakeString("::::::::::::"), PP_FALSE), + PropertyTestData(ID_STR(PP_URLREQUESTPROPERTY_METHOD), + PP_MakeString("INVALID"), PP_FALSE), + PropertyTestData( + ID_STR(PP_URLREQUESTPROPERTY_CUSTOMCONTENTTRANSFERENCODING), + PP_MakeString("invalid"), PP_FALSE), + PropertyTestData( + ID_STR(PP_URLREQUESTPROPERTY_PREFETCHBUFFERUPPERTHRESHOLD), + PP_MakeInt32(-100), PP_FALSE), + PropertyTestData( + ID_STR(PP_URLREQUESTPROPERTY_PREFETCHBUFFERLOWERTHRESHOLD), + PP_MakeInt32(-100), PP_TRUE), + */ + }; + + const PPB_URLRequestInfo* ppb = PPBURLRequestInfo(); + PP_Resource url_request = ppb->Create(pp_instance()); + EXPECT(url_request != kInvalidResource); + + for (size_t i = 0; + i < sizeof(test_data)/sizeof(PropertyTestData); + ++i) { + if (test_data[i].expected_value != + ppb->SetProperty(url_request, + test_data[i].property, + test_data[i].var)) { + nacl::string error_string = nacl::string("Setting property ") + + test_data[i].property_name.c_str() + " to " + + StringifyVar(test_data[i].var) + " did not return " + + StringifyVar(PP_MakeBool(test_data[i].expected_value)); + // PostTestMessage will signal test failure here. + PostTestMessage(__FUNCTION__, error_string.c_str()); + } + PPBVar()->Release(test_data[i].var); + } + + PPBCore()->ReleaseResource(url_request); + TEST_PASSED; +} + + +void LoadAndCompareBody(PP_Resource request, + const nacl::string& expected_body) { + PP_Resource url_loader = PPBURLLoader()->Create(pp_instance()); + EXPECT(url_loader != kInvalidResource); + + TestableCallback callback(pp_instance(), true); + + int32_t result = PPBURLLoader()->Open(url_loader, + request, + callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == result); + result = callback.WaitForResult(); + EXPECT(PP_OK == result); + + PP_Resource response = PPBURLLoader()->GetResponseInfo(url_loader); + EXPECT(response != kInvalidResource); + + PP_Var status = + PPBURLResponseInfo()->GetProperty(response, + PP_URLRESPONSEPROPERTY_STATUSCODE); + EXPECT_VAR_INT(status, 200); + + nacl::string actual_body; + + // Read the entire body in this loop. + for (;;) { + callback.Reset(); + const size_t kBufferSize = 32; + char buf[kBufferSize]; + result = PPBURLLoader()->ReadResponseBody(url_loader, + buf, kBufferSize, + callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == result); + result = callback.WaitForResult(); + EXPECT(result >= PP_OK); + if (result < 0) { + return; + } + if (PP_OK == result) { + break; + } + actual_body.append(buf, result); + } + + EXPECT(actual_body == expected_body); + + PPBCore()->ReleaseResource(response); + PPBCore()->ReleaseResource(url_loader); +} + +void SetupPOSTURLRequest(PP_Resource request) { + const PPB_URLRequestInfo* ppb = PPBURLRequestInfo(); + EXPECT(PP_TRUE == ppb->SetProperty(request, + PP_URLREQUESTPROPERTY_METHOD, + PP_MakeString("POST"))); + EXPECT(PP_TRUE == ppb->SetProperty(request, + PP_URLREQUESTPROPERTY_URL, + PP_MakeString("/echo"))); +} + +void TestAppendDataToBody() { + const PPB_URLRequestInfo* ppb = PPBURLRequestInfo(); + PP_Resource url_request = ppb->Create(pp_instance()); + EXPECT(url_request != kInvalidResource); + nacl::string postdata("sample postdata"); + + // Bad pointer passed in should fail to proxy. + EXPECT(PP_FALSE == ppb->AppendDataToBody(url_request, + NULL, + 1)); + // Invalid resource should fail. + EXPECT(PP_FALSE == ppb->AppendDataToBody(kInvalidResource, + postdata.data(), + postdata.length())); + // Append data and POST to echoing web server. + SetupPOSTURLRequest(url_request); + EXPECT(PP_TRUE == ppb->AppendDataToBody(url_request, + postdata.data(), + postdata.length())); + // Check for success. + LoadAndCompareBody(url_request, postdata); + + PPBCore()->ReleaseResource(url_request); + TEST_PASSED; +} + +// TODO(elijahtaylor): Revisit this function when it is enabled. Parts could be +// factored out and it could be smaller and more readable in general. +void TestAppendFileToBody() { + const int64_t kFileSystemSize = 1024; + const PPB_URLRequestInfo* ppb = PPBURLRequestInfo(); + PP_Resource url_request = ppb->Create(pp_instance()); + EXPECT(url_request != kInvalidResource); + + // Creating a file reference PP_Resource is a multi-stage process. + // First, create and open a new file system. + const PPB_FileSystem* ppb_file_sys = PPBFileSystem(); + PP_Resource file_sys = + ppb_file_sys->Create(pp_instance(), + PP_FILESYSTEMTYPE_EXTERNAL); + EXPECT(file_sys != kInvalidResource); + + TestableCallback callback(pp_instance(), true); + + int32_t result = ppb_file_sys->Open(file_sys, + kFileSystemSize, + callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == result); + result = callback.WaitForResult(); + + EXPECT(PP_OK == result); + + // Create a file reference, then tie it to a new writable file io resource. + PP_Resource file_ref = PPBFileRef()->Create(file_sys, "/foo"); + EXPECT(file_ref != kInvalidResource); + PP_Resource file_io = PPBFileIO()->Create(pp_instance()); + EXPECT(file_ref != kInvalidResource); + + callback.Reset(); + result = PPBFileIO()->Open(file_io, + file_ref, + PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_CREATE | + PP_FILEOPENFLAG_TRUNCATE, + callback.GetCallback()); + + EXPECT(PP_OK_COMPLETIONPENDING == result); + result = callback.WaitForResult(); + EXPECT(PP_OK == result); + + // Now we can write the contents of this string to the file io resource. + nacl::string postdata("sample postdata from file"); + size_t total_written = 0; + for (;;) { + callback.Reset(); + result = PPBFileIO()->Write(file_io, + total_written, + postdata.data() + total_written, + postdata.length() - total_written, + callback.GetCallback()); + + EXPECT(PP_OK_COMPLETIONPENDING == result); + result = callback.WaitForResult(); + + EXPECT(result >= PP_OK); + if (result < 0) + return; + if (result == PP_OK) + break; + total_written += result; + } + PPBFileIO()->Close(file_io); + + const int64_t kReadUntilEOF = -1; + const PP_Time kDummyTimeValue = 5; // seconds since epoch + + // Finally, set up the url_request to post to an echoing web server. + SetupPOSTURLRequest(url_request); + EXPECT(PP_TRUE == ppb->AppendFileToBody(url_request, + file_ref, + 0, // start offset + postdata.length(), + 0)); // expected last modified time + LOG_TO_BROWSER("testing ordinary 'AppendFileToBody'"); + // Check for success. + LoadAndCompareBody(url_request, postdata); + + // Use a new url_request for another POST request + PPBCore()->ReleaseResource(url_request); + url_request = ppb->Create(pp_instance()); + EXPECT(url_request != kInvalidResource); + + callback.Reset(); + // Set the timestamps so we can test 'expected last modified time' + result = PPBFileIO()->Touch(file_ref, + kDummyTimeValue+1, + kDummyTimeValue, + callback.GetCallback()); + + SetupPOSTURLRequest(url_request); + EXPECT(PP_TRUE == ppb->AppendFileToBody(url_request, + file_ref, + 0, // start offset + postdata.length(), + kDummyTimeValue)); + LOG_TO_BROWSER("testing 'expected last modified time'"); + LoadAndCompareBody(url_request, postdata); + + PPBCore()->ReleaseResource(url_request); + url_request = ppb->Create(pp_instance()); + EXPECT(url_request != kInvalidResource); + + SetupPOSTURLRequest(url_request); + // Test for failure on expected last modified time, it won't fail until an + // actual request is made. + EXPECT(PP_TRUE == ppb->AppendFileToBody(url_request, + file_ref, + 0, // start offset + kReadUntilEOF, // number of bytes + kDummyTimeValue - 1)); + LOG_TO_BROWSER("testing 'expected last modified time' failure"); + PP_Resource url_loader = PPBURLLoader()->Create(pp_instance()); + EXPECT(url_loader != kInvalidResource); + callback.Reset(); + + result = PPBURLLoader()->Open(url_loader, + url_request, + callback.GetCallback()); + EXPECT(PP_OK_COMPLETIONPENDING == result); + result = callback.WaitForResult(); + EXPECT(PP_ERROR_FILECHANGED == result); + + // Invalid Resource is failure. + EXPECT(PP_FALSE == ppb->AppendFileToBody(url_request, + kInvalidResource, + 0, // start offset + 1, // length + 0)); // expected last modified time + // Test bad start offset. + EXPECT(PP_FALSE == ppb->AppendFileToBody(url_request, + file_ref, + -1, // start offset + 1, // length + 0)); // expected last modified time + // Test invalid length. (-1 means read until end of file, hence -2) + EXPECT(PP_FALSE == ppb->AppendFileToBody(url_request, + kInvalidResource, + 0, // start offset + -2, // length + 0)); // expected last modified time + PPBCore()->ReleaseResource(url_request); + PPBCore()->ReleaseResource(file_ref); + PPBCore()->ReleaseResource(file_sys); + TEST_PASSED; +} + +// Allocates and manipulates a large number of resources. +void TestStress() { + const int kManyResources = 500; + PP_Resource url_request_info[kManyResources]; + const PPB_URLRequestInfo* ppb = PPBURLRequestInfo(); + + for (int i = 0; i < kManyResources; i++) { + url_request_info[i] = ppb->Create(pp_instance()); + EXPECT(url_request_info[i] != kInvalidResource); + EXPECT(PP_TRUE == ppb->IsURLRequestInfo(url_request_info[i])); + EXPECT(PP_TRUE == ppb->SetProperty(url_request_info[i], + PP_URLREQUESTPROPERTY_STREAMTOFILE, + PP_MakeBool(PP_FALSE))); + } + for (int i = 0; i < kManyResources; i++) { + PPBCore()->ReleaseResource(url_request_info[i]); + EXPECT(PP_FALSE == ppb->IsURLRequestInfo(url_request_info[i])); + } + + TEST_PASSED; +} + +} // namespace + +void SetupTests() { + RegisterTest("TestCreate", TestCreate); + RegisterTest("TestIsURLRequestInfo", TestIsURLRequestInfo); + RegisterTest("TestSetProperty", TestSetProperty); + RegisterTest("TestAppendDataToBody", TestAppendDataToBody); + RegisterTest("TestAppendFileToBody", TestAppendFileToBody); + RegisterTest("TestStress", TestStress); +} + +void SetupPluginInterfaces() { + // none +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_url_request_info/ppapi_ppb_url_request_info.html b/ppapi/native_client/tests/ppapi_browser/ppb_url_request_info/ppapi_ppb_url_request_info.html new file mode 100644 index 0000000..5c33195 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_url_request_info/ppapi_ppb_url_request_info.html @@ -0,0 +1,29 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + <!-- Copyright (c) 2011 Google Inc. All rights reserved. --> + <head> + <META HTTP-EQUIV="Pragma" CONTENT="no-cache" /> + <META HTTP-EQUIV="Expires" CONTENT="-1" /> + <script type="text/javascript" src="nacltest.js"></script> + <script type="text/javascript" src="ppapi_ppb_url_request_info.js"></script> + <title>PPAPI PPB_URLRequestInfo Test</title> + </head> + <body> + <h1>PPAPI PPB_URLRequestInfo Test</h1> + + <embed type="application/x-nacl" id="test_nexe" + name="nacl_module" + src="ppapi_ppb_url_request_info.nmf" + width="0" height="0" /> + + <script type="text/javascript"> + //<![CDATA[ + var tester = new Tester(); + setupTests(tester, $('test_nexe')); + tester.waitFor($('test_nexe')); + tester.run(); + //]]> + </script> + </body> +</html> diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_url_request_info/ppapi_ppb_url_request_info.js b/ppapi/native_client/tests/ppapi_browser/ppb_url_request_info/ppapi_ppb_url_request_info.js new file mode 100644 index 0000000..23932e9 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_url_request_info/ppapi_ppb_url_request_info.js @@ -0,0 +1,20 @@ +// 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. + +function setupTests(tester, plugin) { + function addTest(test_name) { + tester.addAsyncTest('PPB_URLRequestInfo::' + test_name, function(test) { + test.expectMessageSequence(plugin, [test_name + ':PASSED']); + plugin.postMessage(test_name); + }); + } + + addTest("TestCreate"); + addTest("TestIsURLRequestInfo"); + addTest("TestSetProperty"); + addTest("TestAppendDataToBody"); + // TODO(elijahtaylor): enable when crbug.com/90878 is fixed. + //addTest("TestAppendFileToBody"); + addTest("TestStress"); +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_url_request_info/ppapi_ppb_url_request_info.nmf b/ppapi/native_client/tests/ppapi_browser/ppb_url_request_info/ppapi_ppb_url_request_info.nmf new file mode 100644 index 0000000..1d836a6 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_url_request_info/ppapi_ppb_url_request_info.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": { "url": "ppapi_ppb_url_request_info_x86-32.nexe" }, + "x86-64": { "url": "ppapi_ppb_url_request_info_x86-64.nexe" }, + "arm": { "url": "ppapi_ppb_url_request_info_arm.nexe" } + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_var/nacl.scons b/ppapi/native_client/tests/ppapi_browser/ppb_var/nacl.scons new file mode 100644 index 0000000..75398c5 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_var/nacl.scons @@ -0,0 +1,38 @@ +# -*- python -*- +# 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. +# +# This test uses ppapi_test_lib. + +Import('env') + +env.Prepend(CPPDEFINES=['XP_UNIX']) + +nexe = 'ppapi_ppb_var_%s' % env.get('TARGET_FULLARCH') +env.Alias('ppapi_ppb_var${PROGSUFFIX}', ['$STAGING_DIR/%s${PROGSUFFIX}' % nexe]) + +env.ComponentProgram( + nexe, + ['ppapi_ppb_var.cc'], + EXTRA_LIBS=['${PPAPI_LIBS}', + 'ppapi_test_lib', + 'pthread', + 'platform', + 'gio']) + +# Note that the html is required to run this program. +env.Publish(nexe, 'run', + ['ppapi_ppb_var.html', + 'ppapi_ppb_var.nmf', + env.File('${SCONSTRUCT_DIR}/tools/browser_tester/' + 'browserdata/nacltest.js')]) + +node = env.PPAPIBrowserTester('ppapi_ppb_var_browser_test.out', + url='ppapi_ppb_var.html', + files=env.ExtractPublishedFiles(nexe)) + +env.AddNodeToTestSuite(node, + ['chrome_browser_tests'], + 'run_ppapi_ppb_var_browser_test', + is_broken=env.PPAPIBrowserTesterIsBroken()) diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_var/ppapi_ppb_var.cc b/ppapi/native_client/tests/ppapi_browser/ppb_var/ppapi_ppb_var.cc new file mode 100644 index 0000000..f53456e --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_var/ppapi_ppb_var.cc @@ -0,0 +1,118 @@ +// 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 <pthread.h> +#include <stdio.h> +#include <string.h> +#include <new> +#include <vector> + +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/src/shared/ppapi_proxy/plugin_ppb_var.h" +#include "native_client/tests/ppapi_test_lib/get_browser_interface.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" + +#include "ppapi/c/ppb_var.h" + +namespace { + +const int kNumThreads = 100; +const int kNumTriesPerThread = 100; + +const PPB_Var* var_interface = NULL; + +// Creates a bunch of new PP_Var(string), then deletes them. +// This tests locking on the dictionary that looks up PP_Vars. +void* StringCreateDeleteThreadFunc(void* thread_argument) { + PP_Var* vars = new(std::nothrow) PP_Var[kNumTriesPerThread]; + EXPECT(vars); + static const char* kTestString = "A test string"; + const uint32_t kTestStringLen = strlen(kTestString); + for (int i = 0; i < kNumTriesPerThread; ++i) { + vars[i] = + var_interface->VarFromUtf8(pp_module(), kTestString, kTestStringLen); + } + for (int i = 0; i < kNumTriesPerThread; ++i) { + var_interface->Release(vars[i]); + } + delete vars; + return NULL; +} + +// Tests creation and deletion. +// Spawns kNumThreads threads, each of which creates kNumTriesPerThread PP_Vars +// and then calls Release on each of them. +void TestStringVarCreateDelete() { + static pthread_t tids[kNumThreads]; + for (int i = 0; i < kNumThreads; ++i) { + EXPECT(pthread_create(&tids[i], + NULL, + StringCreateDeleteThreadFunc, + NULL) == 0); + } + // Join the threads back before reporting success. + for (int i = 0; i < kNumThreads; ++i) { + EXPECT(pthread_join(tids[i], NULL) == 0); + } + TEST_PASSED; +} + +// Creates a bunch of copies of a single PP_Var(string), then deletes them. +// This tests locked reference counting. +void* StringVarRefCountThreadFunc(void* thread_argument) { + PP_Var* test_var = reinterpret_cast<PP_Var*>(thread_argument); + // Run the ref count up. + for (int i = 0; i < kNumTriesPerThread; ++i) { + var_interface->AddRef(*test_var); + } + // Run the ref count back down. + for (int i = 0; i < kNumTriesPerThread; ++i) { + var_interface->Release(*test_var); + } + // Run the ref count up and down in rapid succession. + for (int i = 0; i < kNumTriesPerThread; ++i) { + var_interface->AddRef(*test_var); + var_interface->Release(*test_var); + } + return NULL; +} + +// Tests reference count atomicity. +// Creates one variable and spawns kNumThreads, each of which does: +// 1) kNumTriesPerThread AddRefs +// 2) kNumTriesPerThread Releases +// 3) kNumTriesPerThread (AddRef, Release) pairs +void TestStringVarRefCount() { + pthread_t tid[kNumThreads]; + static const char* kTestString = "A test string"; + const uint32_t kTestStringLen = strlen(kTestString); + PP_Var test_var = + var_interface->VarFromUtf8(pp_module(), kTestString, kTestStringLen); + for (int i = 0; i < kNumThreads; ++i) { + EXPECT(pthread_create(&tid[i], + NULL, + StringVarRefCountThreadFunc, + &test_var) == 0); + } + // Join the threads back before reporting success. + for (int i = 0; i < kNumThreads; ++i) { + EXPECT(pthread_join(tid[i], NULL) == 0); + } + var_interface->Release(test_var); + TEST_PASSED; +} + +} // namespace + +void SetupTests() { + var_interface = PPBVar(); + EXPECT(var_interface != NULL); + RegisterTest("TestStringVarCreateDelete", TestStringVarCreateDelete); + RegisterTest("TestStringVarRefCount", TestStringVarRefCount); +} + +void SetupPluginInterfaces() { + // none +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_var/ppapi_ppb_var.html b/ppapi/native_client/tests/ppapi_browser/ppb_var/ppapi_ppb_var.html new file mode 100644 index 0000000..3b1faa2 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_var/ppapi_ppb_var.html @@ -0,0 +1,70 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + <!-- Copyright 2011 Google Inc. All rights reserved. --> + <head> + <META HTTP-EQUIV="Pragma" CONTENT="no-cache" /> + <META HTTP-EQUIV="Expires" CONTENT="-1" /> + <script type="text/javascript" src="nacltest.js"></script> + <script type="application/x-javascript"> + //<![CDATA[ + function setupTests(tester, plugin) { + // This function takes an array of messages and asserts that the nexe + // calls PostMessage with each of these messages, in order. + function expectMessages(test, plugin, messages) { + test.assert(messages.length > 0, 'Must provide at least one message'); + var listener = test.wrap(function(message) { + console.log('got a message' + message.data); + plugin.removeEventListener('message', listener, false); + test.assertEqual(message.data, messages.shift()); + if (messages.length == 0) { + test.pass(); + } else { + plugin.addEventListener('message', listener, false); + } + }); + plugin.addEventListener('message', listener, false); + } + + function addTest(test_name, responses) { + if (responses === undefined) { + responses = []; + } + var expected_messages = [test_name + ':PASSED'].concat(responses); + console.log('adding' + test_name); + tester.addAsyncTest('PPB_Var::' + test_name, function(test) { + expectMessages(test, plugin, expected_messages); + plugin.postMessage(test_name) + }); + } + + addTest('TestStringVarCreateDelete'); + /* TestStringVarRefCount is flaky (or the implementation is flaky) + Disabling for now. + http://code.google.com/p/nativeclient/issues/detail?id=2124 + TODO(sehr): file bug in chromium against pepper (and maybe fix it!) + */ + //addTest('TestStringVarRefCount'); + } + //]]> + </script> + <title>PPAPI PPB_Var Test</title> + </head> + <body> + <h1>PPAPI PPB_Core Test</h1> + + <embed type="application/x-nacl" id="test_nexe" + name="nacl_module" + src="ppapi_ppb_var.nmf" + width="0" height="0" /> + + <script type="text/javascript"> + //<![CDATA[ + var tester = new Tester(); + setupTests(tester, $('test_nexe')); + tester.waitFor($('test_nexe')); + tester.run(); + //]]> + </script> + </body> +</html> diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_var/ppapi_ppb_var.nmf b/ppapi/native_client/tests/ppapi_browser/ppb_var/ppapi_ppb_var.nmf new file mode 100644 index 0000000..cfd1ae4 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_var/ppapi_ppb_var.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_ppb_var_x86-32.nexe"}, + "x86-64": {"url": "ppapi_ppb_var_x86-64.nexe"}, + "arm": {"url": "ppapi_ppb_var_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_widget/nacl.scons b/ppapi/native_client/tests/ppapi_browser/ppb_widget/nacl.scons new file mode 100644 index 0000000..2362fbb --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_widget/nacl.scons @@ -0,0 +1,37 @@ +# -*- python -*- +# 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. +# + +Import('env') + +env.Prepend(CPPDEFINES=['XP_UNIX']) + +nexe = 'ppapi_ppb_widget_%s' % env.get('TARGET_FULLARCH') +env.Alias('ppapi_ppb_widget${PROGSUFFIX}', + ['$STAGING_DIR/%s${PROGSUFFIX}' % nexe]) + +ppapi_ppb_widget_nexe = env.ComponentProgram( + nexe, + ['ppapi_ppb_widget.cc'], + EXTRA_LIBS=['${PPAPI_LIBS}', + 'ppapi_test_lib', + 'platform', # for CHECK + 'pthread', + 'gio', + ]) + +env.Publish(nexe, 'run', + ['ppapi_ppb_widget.html', + 'ppapi_ppb_widget.nmf', + 'ppapi_ppb_widget.js']) + +node = env.PPAPIBrowserTester('ppapi_ppb_widget_browser_test.out', + url='ppapi_ppb_widget.html', + files=env.ExtractPublishedFiles(nexe)) + +env.AddNodeToTestSuite(node, + ['chrome_browser_tests'], + 'run_ppapi_ppb_widget_browser_test', + is_broken=env.PPAPIBrowserTesterIsBroken()) diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_widget/ppapi_ppb_widget.cc b/ppapi/native_client/tests/ppapi_browser/ppb_widget/ppapi_ppb_widget.cc new file mode 100644 index 0000000..a04584a --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_widget/ppapi_ppb_widget.cc @@ -0,0 +1,93 @@ +// 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/include/nacl_macros.h" +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/tests/ppapi_test_lib/get_browser_interface.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" +#include "ppapi/c/dev/ppb_scrollbar_dev.h" +#include "ppapi/c/dev/ppb_widget_dev.h" +#include "ppapi/c/pp_bool.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_rect.h" +#include "ppapi/c/ppb_core.h" +#include "ppapi/c/ppb_image_data.h" +#include "ppapi/c/ppb_url_loader.h" +#include "ppapi/c/ppp_messaging.h" + +namespace { + +const PP_Bool kVertical = PP_TRUE; + +// The only widgets that are currently implemented are scrollbars. + +// Test the PPB_Widget_Dev::IsWidget() method. +void TestIsWidget() { + EXPECT(PPBWidgetDev()->IsWidget(kInvalidResource) == PP_FALSE); + EXPECT(PPBWidgetDev()->IsWidget(kNotAResource) == PP_FALSE); + + PP_Resource url_loader = PPBURLLoader()->Create(pp_instance()); + CHECK(url_loader != kInvalidResource); + EXPECT(PPBWidgetDev()->IsWidget(url_loader) == PP_FALSE); + PPBCore()->ReleaseResource(url_loader); + + PP_Resource scrollbar = PPBScrollbarDev()->Create(pp_instance(), kVertical); + EXPECT(PPBWidgetDev()->IsWidget(scrollbar) == PP_TRUE); + + PPBCore()->ReleaseResource(scrollbar); + + EXPECT(PPBWidgetDev()->IsWidget(scrollbar) == PP_FALSE); + + TEST_PASSED; +} + +// Test the PPB_Widget_Dev::GetLocation() and SetLocation() methods. +void TestLocation() { + PP_Resource scrollbar = PPBScrollbarDev()->Create(pp_instance(), kVertical); + PP_Rect location = { {1, 2}, {3, 4} }; + PPBWidgetDev()->SetLocation(scrollbar, &location); + PP_Rect get_location = { {0, 0}, {1, 1} }; + PPBWidgetDev()->GetLocation(scrollbar, &get_location); + EXPECT( + get_location.point.x == location.point.x && + get_location.point.y == location.point.y && + get_location.size.width == location.size.width && + get_location.size.height == location.size.height); + + PP_Rect far_and_big = { {1000000, 1000000}, {1000000, 1000000} }; + PPBWidgetDev()->SetLocation(scrollbar, &far_and_big); + PPBWidgetDev()->GetLocation(scrollbar, &get_location); + EXPECT( + get_location.point.x == far_and_big.point.x && + get_location.point.y == far_and_big.point.y && + get_location.size.width == far_and_big.size.width && + get_location.size.height == far_and_big.size.height); + + PP_Rect neg_location = { {-1, -2}, {3, 4} }; + PPBWidgetDev()->SetLocation(scrollbar, &neg_location); + PPBWidgetDev()->GetLocation(scrollbar, &get_location); + EXPECT( + get_location.point.x == neg_location.point.x && + get_location.point.y == neg_location.point.y && + get_location.size.width == neg_location.size.width && + get_location.size.height == neg_location.size.height); + + // TODO(bbudge) Add test for negative size components. + // http://code.google.com/p/chromium/issues/detail?id=90792 + + PPBCore()->ReleaseResource(scrollbar); + + TEST_PASSED; +} + +} // namespace + +void SetupTests() { + RegisterTest("TestIsWidget", TestIsWidget); + RegisterTest("TestLocation", TestLocation); +} + +void SetupPluginInterfaces() { +} + diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_widget/ppapi_ppb_widget.html b/ppapi/native_client/tests/ppapi_browser/ppb_widget/ppapi_ppb_widget.html new file mode 100644 index 0000000..e214c8c --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_widget/ppapi_ppb_widget.html @@ -0,0 +1,29 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + <!-- Copyright (c) 2011 Google Inc. All rights reserved. --> + <head> + <meta http-equiv="Pragma" content="no-cache" /> + <meta http-equiv="Expires" content="-1" /> + <script type="text/javascript" src="nacltest.js"></script> + <script type="text/javascript" src="ppapi_ppb_widget.js"></script> + <title>PPAPI PPB_Widget_Dev Test</title> + </head> + <body> + <h1>PPAPI PPB_Widget_Dev Test</h1> + + <embed type="application/x-nacl" id="test_nexe" + name="nacl_module" + src="ppapi_ppb_widget.nmf" + width="0" height="0" /> + + <script type="text/javascript"> + //<![CDATA[ + var tester = new Tester(); + setupTests(tester, $('test_nexe')); + tester.waitFor($('test_nexe')); + tester.run(); + //]]> + </script> + </body> +</html> diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_widget/ppapi_ppb_widget.js b/ppapi/native_client/tests/ppapi_browser/ppb_widget/ppapi_ppb_widget.js new file mode 100644 index 0000000..31be616 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_widget/ppapi_ppb_widget.js @@ -0,0 +1,36 @@ +// 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. + +function setupTests(tester, plugin) { + // This function takes an array of messages and asserts that the nexe + // calls PostMessage with each of these messages, in order. + function expectMessages(test, plugin, messages) { + test.assert(messages.length > 0, 'Must provide at least one message'); + var listener = test.wrap(function(message) { + plugin.removeEventListener('message', listener, false); + test.assertEqual(message.data, messages.shift()); + if (messages.length == 0) { + test.pass(); + } else { + plugin.addEventListener('message', listener, false); + } + }); + plugin.addEventListener('message', listener, false); + } + + function addTest(test_name, responses) { + if (responses === undefined) { + responses = []; + } + var expected_messages = [test_name + ':PASSED']; + expected_messages.concat(responses); + tester.addAsyncTest('PPB_Widget::' + test_name, function(test) { + expectMessages(test, plugin, expected_messages); + plugin.postMessage(test_name) + }); + } + + addTest('TestIsWidget'); + addTest('TestLocation'); +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_widget/ppapi_ppb_widget.nmf b/ppapi/native_client/tests/ppapi_browser/ppb_widget/ppapi_ppb_widget.nmf new file mode 100644 index 0000000..8e47490 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppb_widget/ppapi_ppb_widget.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_ppb_widget_x86-32.nexe"}, + "x86-64": {"url": "ppapi_ppb_widget_x86-64.nexe"}, + "arm": {"url": "ppapi_ppb_widget_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppp_input_event/nacl.scons b/ppapi/native_client/tests/ppapi_browser/ppp_input_event/nacl.scons new file mode 100644 index 0000000..22b2eec --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppp_input_event/nacl.scons @@ -0,0 +1,38 @@ +# -*- python -*- +# 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. +# +# This test uses ppapi_test_lib. + +Import('env') + +env.Prepend(CPPDEFINES=['XP_UNIX']) + +nexe = 'ppapi_ppp_input_event_%s' % env.get('TARGET_FULLARCH') +env.Alias('ppapi_ppp_input_event${PROGSUFFIX}', + ['$STAGING_DIR/%s${PROGSUFFIX}' % nexe]) + +ppapi_ppp_input_event_nexe = env.ComponentProgram( + nexe, + ['ppapi_ppp_input_event.cc'], + EXTRA_LIBS=['${PPAPI_LIBS}', + 'ppapi_test_lib', + 'platform', # for CHECK + 'pthread', + 'gio', + ]) + +env.Publish(nexe, 'run', + ['ppapi_ppp_input_event.html', + 'ppapi_ppp_input_event.nmf', + 'ppapi_ppp_input_event.js']) + +node = env.PPAPIBrowserTester('ppapi_ppp_input_event_browser_test.out', + url='ppapi_ppp_input_event.html', + files=env.ExtractPublishedFiles(nexe)) + +env.AddNodeToTestSuite(node, + ['chrome_browser_tests'], + 'run_ppapi_ppp_input_event_browser_test', + is_broken=env.PPAPIBrowserTesterIsBroken()) diff --git a/ppapi/native_client/tests/ppapi_browser/ppp_input_event/ppapi_ppp_input_event.cc b/ppapi/native_client/tests/ppapi_browser/ppp_input_event/ppapi_ppp_input_event.cc new file mode 100644 index 0000000..c2b54294 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppp_input_event/ppapi_ppp_input_event.cc @@ -0,0 +1,214 @@ +// 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 <string.h> + +#include <vector> + +#include "native_client/src/include/nacl/nacl_inttypes.h" +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/tests/ppapi_test_lib/get_browser_interface.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" + +#include "ppapi/c/pp_bool.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_input_event.h" +#include "ppapi/c/ppb_input_event.h" +#include "ppapi/c/ppp_input_event.h" + +namespace { + +// These define whether we want an input event to bubble up to the browser +static enum { + BUBBLE_UNDEFINED, + BUBBLE_YES, + BUBBLE_NO +} bubbleInputEvent; + +PP_TimeTicks last_time_tick; + +std::string InputEventTypeToString(PP_InputEvent_Type type) { + switch (type) { + case PP_INPUTEVENT_TYPE_UNDEFINED: + return "PP_INPUTEVENT_TYPE_UNDEFINED"; + case PP_INPUTEVENT_TYPE_MOUSEDOWN: + return "PP_INPUTEVENT_TYPE_MOUSEDOWN"; + case PP_INPUTEVENT_TYPE_MOUSEUP: + return "PP_INPUTEVENT_TYPE_MOUSEUP"; + case PP_INPUTEVENT_TYPE_MOUSEMOVE: + return "PP_INPUTEVENT_TYPE_MOUSEMOVE"; + case PP_INPUTEVENT_TYPE_MOUSEENTER: + return "PP_INPUTEVENT_TYPE_MOUSEENTER"; + case PP_INPUTEVENT_TYPE_MOUSELEAVE: + return "PP_INPUTEVENT_TYPE_MOUSELEAVE"; + case PP_INPUTEVENT_TYPE_WHEEL: + return "PP_INPUTEVENT_TYPE_WHEEL"; + case PP_INPUTEVENT_TYPE_RAWKEYDOWN: + return "PP_INPUTEVENT_TYPE_RAWKEYDOWN"; + case PP_INPUTEVENT_TYPE_KEYDOWN: + return "PP_INPUTEVENT_TYPE_KEYDOWN"; + case PP_INPUTEVENT_TYPE_KEYUP: + return "PP_INPUTEVENT_TYPE_KEYUP"; + case PP_INPUTEVENT_TYPE_CHAR: + return "PP_INPUTEVENT_TYPE_CHAR"; + case PP_INPUTEVENT_TYPE_CONTEXTMENU: + return "PP_INPUTEVENT_TYPE_CONTEXTMENU"; + default: + std::ostringstream stream; + stream << "Unknown Input Event: " << type; + return stream.str(); + } +} + +std::string InputEventModifierToString(uint32_t modifier) { + struct ModifierStringMap { + PP_InputEvent_Modifier modifier; + const char* name; + }; + static const ModifierStringMap table[] = { + { PP_INPUTEVENT_MODIFIER_SHIFTKEY, "PP_INPUTEVENT_MODIFIER_SHIFTKEY" }, + { PP_INPUTEVENT_MODIFIER_CONTROLKEY, "PP_INPUTEVENT_MODIFIER_CONTROLKEY" }, + { PP_INPUTEVENT_MODIFIER_ALTKEY, "PP_INPUTEVENT_MODIFIER_ALTKEY" }, + { PP_INPUTEVENT_MODIFIER_METAKEY, "PP_INPUTEVENT_MODIFIER_METAKEY" }, + { PP_INPUTEVENT_MODIFIER_ISKEYPAD, "PP_INPUTEVENT_MODIFIER_ISKEYPAD" }, + { PP_INPUTEVENT_MODIFIER_ISAUTOREPEAT, + "PP_INPUTEVENT_MODIFIER_ISAUTOREPEAT" }, + { PP_INPUTEVENT_MODIFIER_LEFTBUTTONDOWN, + "PP_INPUTEVENT_MODIFIER_LEFTBUTTONDOWN" }, + { PP_INPUTEVENT_MODIFIER_MIDDLEBUTTONDOWN, + "PP_INPUTEVENT_MODIFIER_MIDDLEBUTTONDOWN" }, + { PP_INPUTEVENT_MODIFIER_RIGHTBUTTONDOWN, + "PP_INPUTEVENT_MODIFIER_RIGHTBUTTONDOWN" }, + { PP_INPUTEVENT_MODIFIER_CAPSLOCKKEY, + "PP_INPUTEVENT_MODIFIER_CAPSLOCKKEY" }, + { PP_INPUTEVENT_MODIFIER_NUMLOCKKEY, "PP_INPUTEVENT_MODIFIER_NUMLOCKKEY" }, + }; + + std::ostringstream stream; + for (int i = 0; i < int(sizeof(table) / sizeof(*table)); ++i) { + if (table[i].modifier & modifier) { + if (stream.str().size() != 0) { + stream << ","; + } + stream << table[i].name; + modifier &= ~table[i].modifier; + } + } + + if (modifier != 0) { + if (stream.str().size() != 0) { + stream << ","; + } + stream << "Unknown Modifier Bits:" << modifier; + } + return stream.str(); +} + +std::string MouseButtonToString(PP_InputEvent_MouseButton button) { + switch (button) { + case PP_INPUTEVENT_MOUSEBUTTON_NONE: + return "PP_INPUTEVENT_MOUSEBUTTON_NONE"; + case PP_INPUTEVENT_MOUSEBUTTON_LEFT: + return "PP_INPUTEVENT_MOUSEBUTTON_LEFT"; + case PP_INPUTEVENT_MOUSEBUTTON_MIDDLE: + return "PP_INPUTEVENT_MOUSEBUTTON_MIDDLE"; + case PP_INPUTEVENT_MOUSEBUTTON_RIGHT: + return "PP_INPUTEVENT_MOUSEBUTTON_RIGHT"; + default: + std::ostringstream stream; + stream << "Unrecognized (" + << static_cast<int32_t>(button) + << ")"; + return stream.str(); + } +} + +PP_Bool HandleInputEvent(PP_Instance instance, PP_Resource event) { + EXPECT(instance == pp_instance()); + EXPECT(PPBInputEvent()->IsInputEvent(event)); + PP_InputEvent_Type type = PPBInputEvent()->GetType(event); + PP_TimeTicks ticks = PPBInputEvent()->GetTimeStamp(event); + EXPECT(ticks >= last_time_tick); + last_time_tick = ticks; + uint32_t modifiers = PPBInputEvent()->GetModifiers(event); + printf("--- PPP_InputEvent::HandleInputEvent " + "type=%d, ticks=%f, modifiers=%"NACL_PRIu32"\n", + static_cast<int>(type), ticks, modifiers); + std::ostringstream message; + message << InputEventTypeToString(type) << ":" << + InputEventModifierToString(modifiers); + if (PPBMouseInputEvent()->IsMouseInputEvent(event)) { + PP_Point point = PPBMouseInputEvent()->GetPosition(event); + message << ":" << MouseButtonToString( + PPBMouseInputEvent()->GetButton(event)); + message << ":Position=" << point.x << "," << point.y; + message << ":ClickCount=" << PPBMouseInputEvent()->GetClickCount(event); + } + // Here's a example of what a complete response would look like for a mouse + // click (broken into multiple lines for readability): + // HandleInputEvent:PP_INPUTEVENT_TYPE_MOUSEDOWN + // :PP_INPUTEVENT_MODIFIER_LEFTBUTTONDOWN + // :PP_INPUTEVENT_MOUSEBUTTON_LEFT + // :Position=0,0:ClickCount=1 + // TODO(mball) Add output for WheelInputEvent and KeyboardInputEvent + + PostTestMessage("HandleInputEvent", message.str()); + EXPECT(bubbleInputEvent == BUBBLE_YES || bubbleInputEvent == BUBBLE_NO); + return (bubbleInputEvent == BUBBLE_NO) ? PP_TRUE : PP_FALSE; +} + +void TestUnfilteredMouseEvents() { + EXPECT(PPBInputEvent()->RequestInputEvents( + pp_instance(), + PP_INPUTEVENT_CLASS_MOUSE) == PP_OK); + bubbleInputEvent = BUBBLE_NO; + TEST_PASSED; +} + +void TestBubbledMouseEvents() { + EXPECT(PPBInputEvent()->RequestFilteringInputEvents( + pp_instance(), + PP_INPUTEVENT_CLASS_MOUSE) == PP_OK); + bubbleInputEvent = BUBBLE_YES; + TEST_PASSED; +} + +void TestUnbubbledMouseEvents() { + EXPECT(PPBInputEvent()->RequestFilteringInputEvents( + pp_instance(), + PP_INPUTEVENT_CLASS_MOUSE) == PP_OK); + bubbleInputEvent = BUBBLE_NO; + TEST_PASSED; +} + +void Cleanup() { + PPBInputEvent()->ClearInputEventRequest( + pp_instance(), + PP_INPUTEVENT_CLASS_MOUSE | + PP_INPUTEVENT_CLASS_WHEEL | + PP_INPUTEVENT_CLASS_KEYBOARD); + bubbleInputEvent = BUBBLE_UNDEFINED; + TEST_PASSED; +} + +const PPP_InputEvent ppp_input_event_interface = { + &HandleInputEvent +}; + +} // namespace + +void SetupTests() { + bubbleInputEvent = BUBBLE_UNDEFINED; + last_time_tick = 0.0; + RegisterTest("TestUnfilteredMouseEvents", TestUnfilteredMouseEvents); + RegisterTest("TestBubbledMouseEvents", TestBubbledMouseEvents); + RegisterTest("TestUnbubbledMouseEvents", TestUnbubbledMouseEvents); + RegisterTest("Cleanup", Cleanup); +} + +void SetupPluginInterfaces() { + RegisterPluginInterface(PPP_INPUT_EVENT_INTERFACE, + &ppp_input_event_interface); +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppp_input_event/ppapi_ppp_input_event.html b/ppapi/native_client/tests/ppapi_browser/ppp_input_event/ppapi_ppp_input_event.html new file mode 100644 index 0000000..7e9f53d --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppp_input_event/ppapi_ppp_input_event.html @@ -0,0 +1,32 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + <!-- Copyright (c) 2011 Google Inc. All rights reserved. --> + <head> + <meta http-equiv="Pragma" content="no-cache" /> + <meta http-equiv="Expires" content="-1" /> + <script type="text/javascript" src="nacltest.js"></script> + <script type="text/javascript" src="ppapi_ppp_input_event.js"></script> + <title>PPAPI PPP_InputEvent Test</title> + </head> + <body> + <h1>PPAPI PPP_InputEvent Test</h1> + + <div id="test_nexe_parent"> + <embed type="application/x-nacl" id="test_nexe" + name="nacl_module" + src="ppapi_ppp_input_event.nmf" + style="background-color:#AAAAAA" + width="15" height="20" /> + </div> + <br/> + <script type="text/javascript"> + //<![CDATA[ + var tester = new Tester(); + setupTests(tester, $('test_nexe')); + tester.waitFor($('test_nexe')); + tester.run(); + //]]> + </script> + </body> +</html> diff --git a/ppapi/native_client/tests/ppapi_browser/ppp_input_event/ppapi_ppp_input_event.js b/ppapi/native_client/tests/ppapi_browser/ppp_input_event/ppapi_ppp_input_event.js new file mode 100644 index 0000000..b96502e6 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppp_input_event/ppapi_ppp_input_event.js @@ -0,0 +1,89 @@ +// 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. + +function setupTests(tester, plugin) { + ////////////////////////////////////////////////////////////////////////////// + // Test Helpers + ////////////////////////////////////////////////////////////////////////////// + + // These are the coordinates of the upper-left corner of the nacl plugin + // TODO(mball): Avoid hardcoding this location by querying the location + // of the plugin. + var leftCorner = 8, topCorner = 79 + + function simulateMouseEvent(eventName) { + var event = document.createEvent('MouseEvents'); + event.initMouseEvent( + eventName, + true, // bubbles + true, // cancelable + document.defaultView, + 1, // one click + 0, 0, // Screen coordinate + leftCorner, topCorner, // Client coordinate + false, false, false, false, // no key modifiers + 0, // button: 0 - left, 1 - middle, 2 - right + null); // no related targets + plugin.dispatchEvent(event); + } + + function addTest(testName, testCaseEvent, eventResponse, + eventGeneratorCallback) { + tester.addAsyncTest('PPP_InputEvent::' + testName + '_' + testCaseEvent, + function(test) { + var messages = [testName + ':PASSED', + 'HandleInputEvent:' + eventResponse, + 'Cleanup:PASSED']; + // TODO(mball,polina): These listener functions should fail when an event + // is not bubbled up from the Nacl module. + var pluginListener = test.wrap(function(message) { + test.log('plugin received ' + message); + }); + var parentListener = test.wrap(function(message) { + test.log('plugin.parentNode received ' + message); + }); + test.expectMessageSequence( + plugin, messages, + function(message) { + if (message == messages[0]) { + // TODO(polina): why does this forward and bubble the event even + // though it was handled? Based on headers, the listeners below + // should contain test.fail(). Figure out if this is a bug + // (crbug.com/88728) or if the header comments are off. + plugin.addEventListener(testCaseEvent, pluginListener, false); + plugin.parentNode.addEventListener( + testCaseEvent, parentListener, false); + eventGeneratorCallback(testCaseEvent); + } else if (message == messages[1]) { + plugin.removeEventListener(testCaseEvent, pluginListener, false); + plugin.parentNode.removeEventListener( + testCaseEvent, parentListener, false); + plugin.postMessage('Cleanup'); + } else if (message != messages[2]) { + test.fail('Unknown message: ' + message); + } + }); + plugin.postMessage(testName); + }); + } + + ////////////////////////////////////////////////////////////////////////////// + // Tests + ////////////////////////////////////////////////////////////////////////////// + var mouseEventTests = [ + 'TestUnfilteredMouseEvents', + 'TestBubbledMouseEvents', + 'TestUnbubbledMouseEvents']; + + mouseEventTests.map(function(testName) { + addTest( + testName, + 'mousedown', + 'PP_INPUTEVENT_TYPE_MOUSEDOWN' + + ':PP_INPUTEVENT_MODIFIER_LEFTBUTTONDOWN' + + ':PP_INPUTEVENT_MOUSEBUTTON_LEFT' + + ':Position=0,0:ClickCount=1', + simulateMouseEvent); + }); +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppp_input_event/ppapi_ppp_input_event.nmf b/ppapi/native_client/tests/ppapi_browser/ppp_input_event/ppapi_ppp_input_event.nmf new file mode 100644 index 0000000..6063dc7 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppp_input_event/ppapi_ppp_input_event.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_ppp_input_event_x86-32.nexe"}, + "x86-64": {"url": "ppapi_ppp_input_event_x86-64.nexe"}, + "arm": {"url": "ppapi_ppp_input_event_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppp_instance/nacl.scons b/ppapi/native_client/tests/ppapi_browser/ppp_instance/nacl.scons new file mode 100644 index 0000000..d95062d --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppp_instance/nacl.scons @@ -0,0 +1,38 @@ +# -*- python -*- +# 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. +# +# This test uses ppapi_test_lib. + +Import('env') + +env.Prepend(CPPDEFINES=['XP_UNIX']) + +nexe = 'ppapi_ppp_instance_%s' % env.get('TARGET_FULLARCH') +env.Alias('ppapi_ppp_instance${PROGSUFFIX}', + ['$STAGING_DIR/%s${PROGSUFFIX}' % nexe]) + +ppapi_ppp_instance_nexe = env.ComponentProgram( + nexe, + ['ppapi_ppp_instance.cc'], + EXTRA_LIBS=['${PPAPI_LIBS}', + 'ppapi_test_lib', + 'platform', # for CHECK + 'pthread', + 'gio', + ]) + +env.Publish(nexe, 'run', + ['ppapi_ppp_instance.html', + 'ppapi_ppp_instance.nmf', + 'ppapi_ppp_instance.js']) + +node = env.PPAPIBrowserTester('ppapi_ppp_instance_browser_test.out', + url='ppapi_ppp_instance.html', + files=env.ExtractPublishedFiles(nexe)) + +env.AddNodeToTestSuite(node, + ['chrome_browser_tests'], + 'run_ppapi_ppp_instance_browser_test', + is_broken=env.PPAPIBrowserTesterIsBroken()) diff --git a/ppapi/native_client/tests/ppapi_browser/ppp_instance/ppapi_ppp_instance.cc b/ppapi/native_client/tests/ppapi_browser/ppp_instance/ppapi_ppp_instance.cc new file mode 100644 index 0000000..0ee6512 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppp_instance/ppapi_ppp_instance.cc @@ -0,0 +1,91 @@ +// 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 <string.h> + +#include <vector> + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/tests/ppapi_test_lib/get_browser_interface.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" + +#include "ppapi/c/pp_bool.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_input_event.h" +#include "ppapi/c/ppp_instance.h" + +namespace { + +PP_Bool DidCreate(PP_Instance instance, + uint32_t argc, + const char* argn[], + const char* argv[]) { + printf("--- PPP_Instance::DidCreate\n"); + PP_Bool status = DidCreateDefault(instance, argc, argn, argv); + // TEST_PASSED has no effect from this function. + // But as long as the plugin loads and tests are run, we know this succeeded. + // See ppapi_browser/bad for failing DidCreate. + return status; +} + +// This should never be called. +void DidDestroy(PP_Instance instance) { + printf("--- PPP_Instance::DidDestroy\n"); + CHECK(instance == pp_instance()); + NACL_NOTREACHED(); +} + +void DidChangeView(PP_Instance instance, + const struct PP_Rect* position, + const struct PP_Rect* clip) { + printf("--- PPP_Instance::DidChangeView\n"); + EXPECT(instance == pp_instance()); + EXPECT(clip->point.x == 0 && clip->point.y == 0); + // These are based on embed dimensions. + EXPECT(position->size.width == 15 && clip->size.width == 15); + EXPECT(position->size.height == 20 && clip->size.height == 20); + + TEST_PASSED; +} + +void DidChangeFocus(PP_Instance instance, + PP_Bool has_focus) { + printf("--- PPP_Instance::DidChangeFocus has_focus=%d\n", has_focus); + // There should be no focus on load, so this will trigger when we gain it + // and then release it and so on. + static bool expected_has_focus = true; + EXPECT(instance == pp_instance()); + EXPECT(has_focus == expected_has_focus); + expected_has_focus = !expected_has_focus; + + TEST_PASSED; +} + +PP_Bool HandleDocumentLoad(PP_Instance instance, + PP_Resource url_loader) { + // Only called for full-frame plugins. For coverage see: + // tests/ppapi_browser/extension_mime_handler/ + NACL_NOTREACHED(); + return PP_FALSE; +} + +const PPP_Instance ppp_instance_interface = { + DidCreate, + DidDestroy, + DidChangeView, + DidChangeFocus, + HandleDocumentLoad +}; + +} // namespace + + +void SetupTests() { + // Each PPP_Instance function called by the browser acts as a test. +} + +void SetupPluginInterfaces() { + RegisterPluginInterface(PPP_INSTANCE_INTERFACE, &ppp_instance_interface); +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppp_instance/ppapi_ppp_instance.html b/ppapi/native_client/tests/ppapi_browser/ppp_instance/ppapi_ppp_instance.html new file mode 100644 index 0000000..e9e4edd --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppp_instance/ppapi_ppp_instance.html @@ -0,0 +1,33 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + <!-- Copyright (c) 2011 Google Inc. All rights reserved. --> + <head> + <meta http-equiv="Pragma" content="no-cache" /> + <meta http-equiv="Expires" content="-1" /> + <script type="text/javascript" src="nacltest.js"></script> + <script type="text/javascript" src="ppapi_ppp_instance.js"></script> + <title>PPAPI PPP_Instance Test</title> + </head> + <body> + <h1>PPAPI PPP_Instance Test</h1> + + <div id="test_nexe_parent"> + <embed type="application/x-nacl" id="test_nexe" + name="nacl_module" + src="ppapi_ppp_instance.nmf" + style="background-color:#AAAAAA" + width="15" height="20" /> + <!-- NOTE: PPP_Instance::DidChangeView verifies these exact dimenstions --> + </div> + <br> + <script type="text/javascript"> + //<![CDATA[ + var tester = new Tester(); + setupTests(tester, $('test_nexe')); + tester.waitFor($('test_nexe')); + tester.run(); + //]]> + </script> + </body> +</html> diff --git a/ppapi/native_client/tests/ppapi_browser/ppp_instance/ppapi_ppp_instance.js b/ppapi/native_client/tests/ppapi_browser/ppp_instance/ppapi_ppp_instance.js new file mode 100644 index 0000000..e707887 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppp_instance/ppapi_ppp_instance.js @@ -0,0 +1,69 @@ +// 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. + +function startsWith(str, prefix) { + return (str.indexOf(prefix) === 0); +} + +function setupTests(tester, plugin) { + ////////////////////////////////////////////////////////////////////////////// + // Test Helpers + ////////////////////////////////////////////////////////////////////////////// + var numMessages = 0; + function addTestListeners(numListeners, test, testFunction, runCheck) { + var messageListener = test.wrap(function(message) { + if (!startsWith(message.data, testFunction)) return; + test.log(message.data); + numMessages++; + plugin.removeEventListener('message', messageListener, false); + test.assertEqual(message.data, testFunction + ':PASSED'); + if (runCheck) test.assert(runCheck()); + if (numMessages < numListeners) { + plugin.addEventListener('message', messageListener, false); + } else { + numMessages = 0; + test.pass(); + } + }); + plugin.addEventListener('message', messageListener, false); + } + + function addTestListener(test, testFunction, runCheck) { + return addTestListeners(1, test, testFunction, runCheck); + } + + ////////////////////////////////////////////////////////////////////////////// + // Tests + ////////////////////////////////////////////////////////////////////////////// + + tester.addTest('PPP_Instance::DidCreate', function() { + assertEqual(plugin.lastError, ''); + }); + + tester.addAsyncTest('PPP_Instance::DidChangeView', function(test) { + addTestListeners(3, test, 'DidChangeView'); + }); + + tester.addAsyncTest('PPP_Instance::DidChangeFocus', function(test) { + // TODO(polina): How can I simulate focusing on Windows? + // For now just pass explicitely. + if (startsWith(navigator.platform, 'Win')) { + test.log('skipping test on ' + navigator.platform); + test.pass(); + return; + } + addTestListeners(2, test, 'DidChangeFocus'); + plugin.tabIndex = 0; + plugin.focus(); + plugin.blur(); + }); + + // PPP_Instance::HandleDocumentLoad is only used with full-frame plugins. + // This is tested in tests/ppapi_browser/extension_mime_handler/ + + // PPP_Instance::DidDestroy is never invoked in the untrusted code. + // We could wait for a crash event from it, but CallOnMainThread semantics + // on shutdown are still buggy, so it might never come even if the function + // triggered. Plus waiting for something not to happen makes the test flaky. +} diff --git a/ppapi/native_client/tests/ppapi_browser/ppp_instance/ppapi_ppp_instance.nmf b/ppapi/native_client/tests/ppapi_browser/ppp_instance/ppapi_ppp_instance.nmf new file mode 100644 index 0000000..38b768f --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/ppp_instance/ppapi_ppp_instance.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_ppp_instance_x86-32.nexe"}, + "x86-64": {"url": "ppapi_ppp_instance_x86-64.nexe"}, + "arm": {"url": "ppapi_ppp_instance_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/progress_events/nacl.scons b/ppapi/native_client/tests/ppapi_browser/progress_events/nacl.scons new file mode 100644 index 0000000..9d3a973 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/progress_events/nacl.scons @@ -0,0 +1,41 @@ +# -*- python -*- +# 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. + +Import('env') + +# TODO(robertm): those should not be necessary once we go -std=c99 +env.FilterOut(CFLAGS=['-pedantic']) +env.FilterOut(CCFLAGS=['-pedantic']) + +progress_events_sources = env.ComponentObject('ppapi_progress_events.cc'), + +progress_events_target = ('ppapi_progress_events_%s' % + env.get('TARGET_FULLARCH')) +env.ComponentProgram(progress_events_target, + [progress_events_sources], + EXTRA_LIBS=['${PPAPI_LIBS}', + 'ppapi_test_lib', + 'pthread', + 'platform', + 'gio']) + +# Needed by other tests using progress events. +env.Publish(progress_events_target, 'run', [ + 'ppapi_progress_events.html', + 'ppapi_progress_events.nmf', + ('${SCONSTRUCT_DIR}/tests/ppapi_browser/progress_events/' + + 'ppapi_progress_events.js'), + '${SCONSTRUCT_DIR}/tools/browser_tester/browserdata/nacltest.js', +]) + +node = env.PPAPIBrowserTester( + 'ppapi_progress_events_browser_test.out', + url='ppapi_progress_events.html', + files=env.ExtractPublishedFiles(progress_events_target)) + +env.AddNodeToTestSuite(node, + ['chrome_browser_tests'], + 'run_ppapi_progress_events_browser_test', + is_broken=env.PPAPIBrowserTesterIsBroken()) diff --git a/ppapi/native_client/tests/ppapi_browser/progress_events/ppapi_progress_events.cc b/ppapi/native_client/tests/ppapi_browser/progress_events/ppapi_progress_events.cc new file mode 100644 index 0000000..aed22d5 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/progress_events/ppapi_progress_events.cc @@ -0,0 +1,13 @@ +// 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/tests/ppapi_test_lib/test_interface.h" + +void SetupTests() { + // none +} + +void SetupPluginInterfaces() { + // none +} diff --git a/ppapi/native_client/tests/ppapi_browser/progress_events/ppapi_progress_events.html b/ppapi/native_client/tests/ppapi_browser/progress_events/ppapi_progress_events.html new file mode 100644 index 0000000..f91fff6 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/progress_events/ppapi_progress_events.html @@ -0,0 +1,48 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> +<!-- 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. --> +<head> + <title>PPAPI Runtime Feature Test</title> + <meta HTTP-EQUIV="Pragma" CONTENT="no-cache" /> + <meta HTTP-EQUIV="Expires" CONTENT="-1" /> + <script type="text/javascript" src="nacltest.js"></script> + <script type="text/javascript" src="ppapi_progress_events.js"></script> +</head> + +<body id="body"> +<script type="text/javascript"> +//<![CDATA[ +var tester = new Tester($('body')); +testProgressEventStateMachine( + tester, + 'progress_events', + 2, // progressMinCount + 0, // errorCount + 0, // abortCount + 1, // loadCount + undefined // lastError +); +function runTests() { + tester.waitFor($('progress_events')); + tester.run(); +} +// Set all the listeners on the body. +setListeners($('body')); +//]]> +</script> + +<embed id="progress_events" + class="naclModule" + width=0 height=0 + src="ppapi_progress_events.nmf" + type="application/x-nacl" /> +<script type="text/javascript"> +//<![CDATA[ +runTests(); +//]]> +</script> +</body> +</html> diff --git a/ppapi/native_client/tests/ppapi_browser/progress_events/ppapi_progress_events.js b/ppapi/native_client/tests/ppapi_browser/progress_events/ppapi_progress_events.js new file mode 100644 index 0000000..65e264e --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/progress_events/ppapi_progress_events.js @@ -0,0 +1,149 @@ +// 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. + +// Class to track the progress events received by a particular plugin instance. +function EventStateMachine() { + // Work around how JS binds 'this'. + var this_ = this; + // Given a particular state, what are the acceptable event types. + this.expectedNext = { + 'BEGIN': { 'loadstart': 1 }, + 'loadstart': { 'progress': 1, 'error': 1, 'abort': 1, 'load': 1 }, + 'progress': { 'progress': 1, 'error': 1, 'abort': 1, 'load': 1 }, + 'error': { 'loadend': 1 }, + 'abort': { 'loadend': 1 }, + 'load': { 'loadend': 1 }, + 'loadend': { }, + 'UNEXPECTED': { }, + }; + // The current state (and index into expectedNext). + this.currentState = 'BEGIN'; + // For each recognized state, a count of the times it was reached. + this.stateHistogram = { + 'BEGIN': 0, + 'loadstart': 0, + 'progress': 0, + 'error': 0, + 'abort': 0, + 'load': 0, + 'loadend': 0, + 'UNEXPECTED': 0 + }; + // The state transition function. + this.transitionTo = function(event_type) { + // The index values of this_.expectedNext are the only valid states. + // Invalid event types are normalized to 'UNEXPECTED'. + if (this_.expectedNext[event_type] == undefined) { + console.log('unexpected ' + event_type); + event_type = 'UNEXPECTED'; + } + // Check that the next event type is expected from the current state. + // If not, we transition to the state 'UNEXPECTED'. + if (!(event_type in this_.expectedNext[this_.currentState])) { + console.log('unexpected ' + event_type + ' from ' + this_.currentState); + event_type = 'UNEXPECTED'; + } + this_.currentState = event_type; + this_.stateHistogram[this_.currentState]++; + } +} + +// event_machines is a collection of EventStateMachines, one for each element +// id that dispatches an event of a type we are listening for. +window.event_machines = { }; +// Look up the EventStateMachine for the id. +function lookupEventMachine(element_id) { + var event_machine = window.event_machines[element_id]; + if (event_machine == undefined) { + // This is the first event for this target. Create an EventStateMachine. + event_machine = new EventStateMachine(); + window.event_machines[element_id] = event_machine; + } + return event_machine; +} +// Sets up event listeners on the body element for all the progress +// event types. Delegation to the body allows this to be done only once +// per document. +var setListeners = function(body_element) { + var eventListener = function(e) { + // Find the target element of the event. + var target_element = e.target; + // Body only dispatches for elements having the 'naclModule' CSS class. + if (target_element.className != 'naclModule') { + return; + } + var element_id = target_element.id; + // Look up the EventStateMachine for the target of the event. + var event_machine = lookupEventMachine(element_id); + // Update the state of the machine. + event_machine.transitionTo(e.type); + } + // Add the listener for all of the ProgressEvent event types. + body_element.addEventListener('loadstart', eventListener, true); + body_element.addEventListener('progress', eventListener, true); + body_element.addEventListener('error', eventListener, true); + body_element.addEventListener('abort', eventListener, true); + body_element.addEventListener('load', eventListener, true); + body_element.addEventListener('loadend', eventListener, true); +} + +// Performs some tests to make sure that progress events follow the expected +// state transitions to end in an expected state. +function testProgressEventStateMachine(tester, + embedId, + progressMinCount, + errorCount, + abortCount, + loadCount, + lastError) { + var eventMachine = lookupEventMachine(embedId); + // Test the expected number of occurrences, with some duplication. + tester.addTest('begin_count_' + embedId, function() { + // There should be no 'BEGIN' event. + assertEqual(eventMachine.stateHistogram['BEGIN'], 0); + }); + tester.addTest('loadstart_count_' + embedId, function() { + // There should be one 'loadstart' event. + assertEqual(eventMachine.stateHistogram['loadstart'], 1); + }); + tester.addTest('progress_min_count_' + embedId, function() { + // There should be at least one progress event when the manifest file is + // loaded and another when the .nexe is loaded. + assert(eventMachine.stateHistogram['progress'] >= progressMinCount); + }); + tester.addTest('error_count_' + embedId, function() { + // Check that the right number of 'error' events were dispatched. + assertEqual(eventMachine.stateHistogram['error'], errorCount); + }); + tester.addTest('abort_count_' + embedId, function() { + // Check that the right number of 'abort' events were dispatched. + assertEqual(eventMachine.stateHistogram['abort'], abortCount); + }); + tester.addTest('load_count_' + embedId, function() { + // Check that the right number of 'load' events were dispatched. + assertEqual(eventMachine.stateHistogram['load'], loadCount); + }) + tester.addTest('loadend_count_' + embedId, function() { + // There should be one 'loadend' event. + assertEqual(eventMachine.stateHistogram['loadend'], 1); + }); + tester.addTest('unexpected_count_' + embedId, function() { + // There should be no 'UNEXPECTED' event. + assertEqual(eventMachine.stateHistogram['UNEXPECTED'], 0); + }); + tester.addTest('end_state_' + embedId, function() { + // Test that the progress events followed the expected sequence to + // completion in the 'loadend' state. + assertEqual(eventMachine.currentState, 'loadend'); + }); + tester.addTest('last_error_string_' + embedId, function() { + // If an error or abort was reported, check that lastError is set + // to the correct value. + if ((eventMachine.stateHistogram['error'] > 0 || + eventMachine.stateHistogram['abort'] > 0)) { + var embed = $(embedId); + assertEqual(embed.lastError, lastError); + } + }); +} diff --git a/ppapi/native_client/tests/ppapi_browser/progress_events/ppapi_progress_events.nmf b/ppapi/native_client/tests/ppapi_browser/progress_events/ppapi_progress_events.nmf new file mode 100644 index 0000000..d4d05ca --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/progress_events/ppapi_progress_events.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_progress_events_x86-32.nexe"}, + "x86-64": {"url": "ppapi_progress_events_x86-64.nexe"}, + "arm": {"url": "ppapi_progress_events_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_browser/stress_many_nexes/nacl.scons b/ppapi/native_client/tests/ppapi_browser/stress_many_nexes/nacl.scons new file mode 100644 index 0000000..a961c0e --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/stress_many_nexes/nacl.scons @@ -0,0 +1,32 @@ +# -*- python -*- +# 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. + + +Import('env') + +stress_files = [ + env.File('stress_many_nexes.html'), + env.File('${SCONSTRUCT_DIR}/tools/browser_tester/browserdata/nacltest.js'), + ] +replicated_files = env.Replicate('${STAGING_DIR}', stress_files) +env.Alias('all_programs', replicated_files) + +core = env.File('${STAGING_DIR}/ppapi_ppb_core_${TARGET_FULLARCH}${PROGSUFFIX}') +nmf = env.File('${STAGING_DIR}/ppapi_ppb_core.nmf') +stress_files.extend([core, nmf]) + +node = env.PPAPIBrowserTester( + 'stress_many_nexes_test.out', + url='stress_many_nexes.html', + test_args=(('count', 100), ('parallel', 0)), + timeout=200, + files=stress_files) + +env.AddNodeToTestSuite(node, + ['chrome_browser_tests'], + 'run_stress_many_nexes_test', + # Don't run this test automatically. It can cause random + # processes to die on a machine, etc. + is_broken=True) diff --git a/ppapi/native_client/tests/ppapi_browser/stress_many_nexes/stress_many_nexes.html b/ppapi/native_client/tests/ppapi_browser/stress_many_nexes/stress_many_nexes.html new file mode 100644 index 0000000..07ae6a4 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_browser/stress_many_nexes/stress_many_nexes.html @@ -0,0 +1,87 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + <!-- + 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. + --> + <head> + <META HTTP-EQUIV="Pragma" CONTENT="no-cache" /> + <META HTTP-EQUIV="Expires" CONTENT="-1" /> + <script type="text/javascript" src="nacltest.js"> </script> + <title>Browser Stress Test</title> + <style type="text/css"> + .naclModule { background-color: gray; margin: 2px 2px; } + .naclPassed { background-color: green; margin: 2px 2px; } + .naclFailed { background-color: red; margin: 2px 2px; } + </style> + </head> + <body id="body"> +<script type="text/javascript"> +//<![CDATA[ + +function createEmbed(id) { + return createNaClEmbed({ + id: id, + src: 'ppapi_ppb_core.nmf', + width: 100, + height: 20 + }); +} + + +function checkEmbed(test, embed) { + embed.className = 'naclFailed'; + test.assertEqual(embed.readyState, 4); + test.assertEqual(embed.lastError, ''); + embed.className = 'naclPassed'; + test.pass(); +} + + +function addParallelTest(tester, i) { + var name = 'nacl_' + i; + var embed = createEmbed(name); + tester.waitFor(embed); + tester.addAsyncTest(name, function(test) { + checkEmbed(test, embed); + }); + document.body.appendChild(embed); +} + + +function addSerialTest(tester, i) { + var name = 'nacl_' + i; + tester.addAsyncTest(name, function(test){ + var embed = createEmbed(name); + test.expectEvent(embed, 'loadend', function() { + checkEmbed(test, embed); + }); + document.body.appendChild(embed); + }); +} + + +function initTests(tester) { + var args = getTestArguments({'count': '100', 'parallel': '0'}); + for (var i = 0; i < args.count; i++) { + if (parseInt(args.parallel)) { + // Faster, lets the browser determine load order and interleaving. + addParallelTest(tester, i); + } else { + // Slower, forces sequential load order. + addSerialTest(tester, i); + } + } +} + + +var tester = new Tester($('body')); +initTests(tester); +tester.run(); + + //]]> + </script> + </body> +</html> diff --git a/ppapi/native_client/tests/ppapi_example_2d/nacl.scons b/ppapi/native_client/tests/ppapi_example_2d/nacl.scons new file mode 100644 index 0000000..04c0682 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_example_2d/nacl.scons @@ -0,0 +1,22 @@ +# -*- python -*- +# 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. + +# This is a Pepper 2D example from ppapi/examples/2d. + +Import('env') + +env.Prepend(CPPDEFINES=['XP_UNIX']) + +nexe_name = 'ppapi_example_2d_%s' % env.get('TARGET_FULLARCH') +obj = env.ComponentObject( + 'graphics_2d_example', + '$SOURCE_ROOT/ppapi/examples/2d/graphics_2d_example.c' + ) +ppapi_example_2d_nexe = env.ComponentProgram(nexe_name, [obj], + EXTRA_LIBS=['${PPAPI_LIBS}']) + +# Note that the html is required to run this program. +env.Publish(nexe_name, 'run', + ['ppapi_example_2d.html', 'ppapi_example_2d.nmf' ]) diff --git a/ppapi/native_client/tests/ppapi_example_2d/ppapi_example_2d.html b/ppapi/native_client/tests/ppapi_example_2d/ppapi_example_2d.html new file mode 100644 index 0000000..906ef29 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_example_2d/ppapi_example_2d.html @@ -0,0 +1,25 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + <!-- Copyright 2010 Google Inc. All rights reserved. --> + <head> + <META HTTP-EQUIV="Pragma" CONTENT="no-cache" /> + <META HTTP-EQUIV="Expires" CONTENT="-1" /> + </head> + <h1>Native Client PPAPI Graphics2D</h1> + <body> + <embed id="naclModule" + name="naclModule" + width=400 height=400 + src="ppapi_example_2d.nmf" + style="background-color:gray" + type="application/x-nacl" /> + <br>Resize the window for repaint to trigger.<br> + <table> + <tr> <td align="center"> <em> Legend </em> + <tr> <td align="center" style="background-color:blue">Test passed + <tr> <td align="center" style="background-color:gray">Test failed + </table> + + </body> +</html> diff --git a/ppapi/native_client/tests/ppapi_example_2d/ppapi_example_2d.nmf b/ppapi/native_client/tests/ppapi_example_2d/ppapi_example_2d.nmf new file mode 100644 index 0000000..56da2ee --- /dev/null +++ b/ppapi/native_client/tests/ppapi_example_2d/ppapi_example_2d.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_example_2d_x86-32.nexe"}, + "x86-64": {"url": "ppapi_example_2d_x86-64.nexe"}, + "arm": {"url": "ppapi_example_2d_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_example_audio/audio.cc b/ppapi/native_client/tests/ppapi_example_audio/audio.cc new file mode 100644 index 0000000..25ec3b5 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_example_audio/audio.cc @@ -0,0 +1,302 @@ +// 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 <nacl/nacl_log.h> + +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <cmath> +#include <limits> +#include <string> +#include <nacl/nacl_inttypes.h> + +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "ppapi/c/pp_bool.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/ppb_audio.h" +#include "ppapi/c/ppb_audio_config.h" +#include "ppapi/cpp/audio.h" +#include "ppapi/cpp/audio_config.h" +#include "ppapi/cpp/completion_callback.h" +#include "ppapi/cpp/instance.h" +#include "ppapi/cpp/module.h" +#include "ppapi/cpp/var.h" + + +// Most of this example is borrowed from ppapi/examples/audio/audio.cc + +// Separate left and right frequency to make sure we didn't swap L & R. +// Sounds pretty horrible, though... +const double kDefaultFrequencyLeft = 400.0; +const double kDefaultFrequencyRight = 1000.0; +const uint32_t kDefaultDuration = 10000; + +// This sample frequency is guaranteed to work. +const PP_AudioSampleRate kSampleFrequency = PP_AUDIOSAMPLERATE_44100; +// Buffer size in units of sample frames. +// 4096 is a conservative size that should avoid underruns on most systems. +const uint32_t kSampleFrameCount = 4096; + +const double kPi = 3.141592653589; +const double kTwoPi = 2.0 * kPi; + +void LogFailure(const char* msg) { + NaClLog(LOG_ERROR, "\n*** FAILURE **** example: %s", msg); +} + +class MyInstance : public pp::Instance { + private: + void ParseArgs(uint32_t argc, const char* argn[], const char* argv[]) { + NaClLog(1, "example: parsing %d args\n", static_cast<int>(argc)); + for (uint32_t i = 0; i < argc; ++i) { + NaClLog(1, "example: arg %d: [%s] [%s]\n", + static_cast<int>(i), argn[i], argv[i]); + const std::string tag = argn[i]; + if (tag == "frequency_l") frequency_l_ = strtod(argv[i], 0); + if (tag == "frequency_r") frequency_r_ = strtod(argv[i], 0); + if (tag == "amplitude_l") amplitude_l_ = strtod(argv[i], 0); + if (tag == "amplitude_r") amplitude_r_ = strtod(argv[i], 0); + if (tag == "duration_msec") duration_msec_ = strtod(argv[i], 0); + if (tag == "basic_tests") basic_tests_ = (0 != atoi(argv[i])); + if (tag == "stress_tests") stress_tests_ = (0 != atoi(argv[i])); + if (tag == "headless") headless_ = (0 != atoi(argv[i])); + // ignore other tags + } + } + + public: + explicit MyInstance(PP_Instance instance) + : pp::Instance(instance), + config_(NULL), + audio_(NULL), + audio_wave_l_(0.0), + audio_wave_r_(0.0), + frequency_l_(kDefaultFrequencyLeft), + frequency_r_(kDefaultFrequencyRight), + amplitude_l_(1.0), + amplitude_r_(1.0), + headless_(false), + basic_tests_(false), + stress_tests_(false), + duration_msec_(kDefaultDuration), + obtained_sample_frame_count_(0), + callback_count_(0) {} + + virtual void HandleMessage(const pp::Var& message) { + NaClLog(1, "example: received HandleMessage\n"); + if (message.is_string()) { + if (message.AsString() == "StartPlayback") { + StartOutput(); + } + } + } + + void StartOutput() { + bool audio_start_playback = audio_->StartPlayback(); + CHECK(true == audio_start_playback); + NaClLog(1, "example: frequencies are %f %f\n", frequency_l_, frequency_r_); + NaClLog(1, "example: amplitudes are %f %f\n", amplitude_l_, amplitude_r_); + NaClLog(1, "example: Scheduling StopOutput on main thread in %" + NACL_PRIu32"msec\n", duration_msec_); + // Schedule a callback in duration_msec_ to stop audio output + pp::CompletionCallback cc(StopOutput, this); + pp::Module::Get()->core()->CallOnMainThread(duration_msec_, cc, PP_OK); + } + + static void StopOutput(void* user_data, int32_t err) { + MyInstance* instance = static_cast<MyInstance*>(user_data); + + const int kMaxResult = 256; + char result[kMaxResult]; + NaClLog(1, "example: StopOutput() invoked on main thread\n"); + if (PP_OK == err) { + if (instance->audio_->StopPlayback()) { + // In headless mode, the build bots may not have an audio driver, in + // which case the callback won't be invoked. + // TODO(nfullagar): Other ways to determine if machine has audio + // capabilities. Currently PPAPI returns a valid resource regardless. + if ((instance->callback_count_ >= 2) || instance->headless_) { + snprintf(result, kMaxResult, "StopOutput:PASSED"); + } else { + snprintf(result, kMaxResult, "StopOutput:FAILED - too " + "few callbacks (only %d callbacks detected)", + static_cast<int>(instance->callback_count_)); + } + } + } else { + snprintf(result, kMaxResult, + "StopOutput: FAILED - returned err is %d", static_cast<int>(err)); + } + // Release audio & config instance. + delete instance->audio_; + delete instance->config_; + instance->audio_ = NULL; + instance->config_ = NULL; + // At this point the test has finished, report result. + pp::Var message(result); + instance->PostMessage(message); + } + + // To enable basic tests, use basic_tests="1" in the embed tag. + void BasicTests() { + // Verify obtained_sample_frame_count isn't out of range. + CHECK(obtained_sample_frame_count_ >= PP_AUDIOMINSAMPLEFRAMECOUNT); + CHECK(obtained_sample_frame_count_ <= PP_AUDIOMAXSAMPLEFRAMECOUNT); + // Do some sanity checks below; verify c & cpp interfaces agree. + // Note: This is test code and is not normally needed for an application. + PPB_GetInterface get_browser_interface = + pp::Module::Get()->get_browser_interface(); + const struct PPB_AudioConfig* audio_config_interface = + static_cast<const struct PPB_AudioConfig*>( + get_browser_interface(PPB_AUDIO_CONFIG_INTERFACE)); + const struct PPB_Audio* audio_interface = + static_cast<const struct PPB_Audio*>( + get_browser_interface(PPB_AUDIO_INTERFACE)); + PP_Resource audio_config_resource = config_->pp_resource(); + PP_Resource audio_resource = audio_->pp_resource(); + NaClLog(1, "example: audio config resource: %"NACL_PRId32"\n", + audio_config_resource); + NaClLog(1, "example: audio resource: %"NACL_PRId32"\n", audio_resource); + CHECK(PP_TRUE == audio_config_interface-> + IsAudioConfig(audio_config_resource)); + CHECK(PP_TRUE == audio_interface->IsAudio(audio_resource)); + CHECK(PP_FALSE == audio_config_interface->IsAudioConfig(audio_resource)); + CHECK(PP_FALSE == audio_interface->IsAudio(audio_config_resource)); + CHECK(audio_interface->GetCurrentConfig(audio_resource) == + audio_config_resource); + CHECK(0 == audio_interface->GetCurrentConfig(audio_config_resource)); + CHECK(audio_config_interface->GetSampleRate(audio_config_resource) == + config_->sample_rate()); + CHECK(audio_config_interface->GetSampleFrameCount(audio_config_resource) == + config_->sample_frame_count()); + CHECK(audio_->config().pp_resource() == audio_config_resource); + } + + // To enable stress tests, use stress_tests="1" in the embed tag. + void StressTests() { + // Attempt to create many audio devices, then immediately shut them down. + // Chrome may generate some warnings on the console, but should not crash. + const int kNumManyAudio = 1000; + pp::Audio* many_audio[kNumManyAudio]; + for (int i = 0; i < kNumManyAudio; ++i) + many_audio[i] = new pp::Audio(this, *config_, SilenceCallback, this); + for (int i = 0; i < kNumManyAudio; ++i) + CHECK(true == many_audio[i]->StartPlayback()); + for (int i = 0; i < kNumManyAudio; ++i) + delete many_audio[i]; + } + + void TestSuite() { + if (basic_tests_) + BasicTests(); + if (stress_tests_) + StressTests(); + } + + virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) { + ParseArgs(argc, argn, argv); + obtained_sample_frame_count_ = pp::AudioConfig::RecommendSampleFrameCount( + kSampleFrequency, kSampleFrameCount); + config_ = new + pp::AudioConfig(this, kSampleFrequency, obtained_sample_frame_count_); + CHECK(NULL != config_); + audio_ = new pp::Audio(this, *config_, SineWaveCallback, this); + CHECK(NULL != audio_); + // Run through test suite before attempting real playback. + TestSuite(); + return true; + } + + private: + static void SineWaveCallback(void* samples, uint32_t num_bytes, void* thiz) { + MyInstance* instance = reinterpret_cast<MyInstance*>(thiz); + const double delta_l = kTwoPi * instance->frequency_l_ / kSampleFrequency; + const double delta_r = kTwoPi * instance->frequency_r_ / kSampleFrequency; + + // Verify num_bytes and obtained_sample_frame_count match up. + const int kNumChannelsForStereo = 2; + const int kSizeOfSample = sizeof(int16_t); + const size_t single_sample = kNumChannelsForStereo * kSizeOfSample; + + // CHECK inside callback is only for testing purposes. + CHECK(instance->obtained_sample_frame_count_ * single_sample == num_bytes); + + // Use per channel audio wave value to avoid clicks on buffer boundries. + double wave_l = instance->audio_wave_l_; + double wave_r = instance->audio_wave_r_; + const int16_t max_int16 = std::numeric_limits<int16_t>::max(); + int16_t* buf = reinterpret_cast<int16_t*>(samples); + for (size_t i = 0; i < instance->obtained_sample_frame_count_; ++i) { + const double l = sin(wave_l) * instance->amplitude_l_ * max_int16; + const double r = sin(wave_r) * instance->amplitude_r_ * max_int16; + *buf++ = static_cast<int16_t>(l); + *buf++ = static_cast<int16_t>(r); + // Add delta, keep within -kTwoPi..kTwoPi to preserve precision. + wave_l += delta_l; + if (wave_l > kTwoPi) + wave_l -= kTwoPi * 2.0; + wave_r += delta_r; + if (wave_r > kTwoPi) + wave_r -= kTwoPi * 2.0; + } + // Store current value to use as starting point for next callback. + instance->audio_wave_l_ = wave_l; + instance->audio_wave_r_ = wave_r; + + ++instance->callback_count_; + } + + static void SilenceCallback(void* samples, uint32_t num_bytes, void* thiz) { + memset(samples, 0, num_bytes); + } + + // Audio config resource. Allocated in Init(). + pp::AudioConfig* config_; + + // Audio resource. Allocated in Init(). + pp::Audio* audio_; + + // Current audio wave position, used to prevent sine wave skips + // on buffer boundaries. + double audio_wave_l_; + double audio_wave_r_; + + double frequency_l_; + double frequency_r_; + + double amplitude_l_; + double amplitude_r_; + + bool headless_; + + bool basic_tests_; + bool stress_tests_; + + uint32_t duration_msec_; + uint32_t obtained_sample_frame_count_; + + int callback_count_; +}; + +class MyModule : public pp::Module { + public: + // Override CreateInstance to create your customized Instance object. + virtual pp::Instance* CreateInstance(PP_Instance instance) { + return new MyInstance(instance); + } +}; + +namespace pp { + +// Factory function for your specialization of the Module object. +Module* CreateModule() { + NaClLogModuleInit(); + return new MyModule(); +} + +} // namespace pp diff --git a/ppapi/native_client/tests/ppapi_example_audio/nacl.scons b/ppapi/native_client/tests/ppapi_example_audio/nacl.scons new file mode 100644 index 0000000..cb28a72 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_example_audio/nacl.scons @@ -0,0 +1,40 @@ +# -*- python -*- +# 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. + +# This is a pepper audio example from examples/audio. + +Import('env') + +env.Prepend(CPPDEFINES=['XP_UNIX']) + +nexe_name = 'ppapi_example_audio_%s' % env.get('TARGET_FULLARCH') +nexe = env.ComponentProgram(nexe_name, + [ 'audio.cc' ], + EXTRA_LIBS=['${PPAPI_LIBS}', + 'ppapi_cpp', + 'platform', + 'gio', + 'pthread', + 'm']) + +# Note that the html is required to run this program. +env.Publish(nexe_name, 'run', + ['ppapi_example_audio.html' , 'ppapi_example_audio.nmf']) + +test = env.PPAPIBrowserTester('ppapi_example_audio_test.out', + url='ppapi_example_audio.html#mute', + files=[nexe, + env.File('ppapi_example_audio.nmf'), + env.File('ppapi_example_audio.html')]) + +# Though this tests passes locally, it does not pass on the Windows +# and Linux buildbots, which do not have audio devices. Although +# StartPlayback() and StopPlayback() succeed, the audio callback is +# not called. However, this does work on the Mac buildbots. +is_broken = env.PPAPIBrowserTesterIsBroken() or not env.Bit('host_mac') +env.AddNodeToTestSuite(test, + ['chrome_browser_tests'], + 'run_ppapi_example_audio_test', + is_broken=is_broken) diff --git a/ppapi/native_client/tests/ppapi_example_audio/ppapi_example_audio.html b/ppapi/native_client/tests/ppapi_example_audio/ppapi_example_audio.html new file mode 100644 index 0000000..3523cb5 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_example_audio/ppapi_example_audio.html @@ -0,0 +1,71 @@ +<!-- + Copyright 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. +--> + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + <head> + <META HTTP-EQUIV="Pragma" CONTENT="no-cache" /> + <META HTTP-EQUIV="Expires" CONTENT="-1" /> + <script type="text/javascript" src="nacltest.js"></script> + <title>PPAPI Audio</title> + </head> + + <body> + <h1>Native Client PPAPI Audio</h1> + <div id="attach"></div> + <br />Verify that a 400Hz tone is emitted on the left channel.<br /> + <br />Verify that a 1000Hz tone is emitted on the right + channel.<br /> + <br />Note: This example depends on your system supporting audio + output.<br /> + + <script type="text/javascript"> + //<![CDATA[ +function setupTests(tester, plugin) { + + tester.addAsyncTest('TestPlayback', function(status) { + // Register a message listener to receive test result. + var messageListener = status.wrap(function(message) { + status.log('Received message: ' + message.data); + plugin.removeEventListener('message', messageListener, false); + status.assertEqual(message.data, 'StopOutput:PASSED'); + status.pass(); + }); + plugin.addEventListener("message", messageListener, false); + + // Tell the nexe to start playing audio. + plugin.postMessage('StartPlayback'); + }); +} + +var playback; +if (location.hash == "#mute") { + playback = 'amplitude_l="0" amplitude_r="0" duration_msec="1000"' + + 'headless="1"'; +} else { + playback = 'amplitude_l="1" amplitude_r="1" duration_msec="10000"'; +} +var node = document.createElement('div'); +node.innerHTML = '<embed id="naclModule" ' + + 'name="naclModule" ' + + 'width=0 height=0 ' + + 'src="ppapi_example_audio.nmf" ' + + 'basic_tests="1" ' + + 'stress_tests="0" ' + + 'style="background-color:gray" ' + + 'type="application/x-nacl" ' + + playback + ' />'; +document.getElementById('attach').appendChild(node); + +var tester = new Tester(); +setupTests(tester, $('naclModule')); +tester.waitFor($('naclModule')); +tester.run(); + //]]> + </script> + </body> +</html> diff --git a/ppapi/native_client/tests/ppapi_example_audio/ppapi_example_audio.nmf b/ppapi/native_client/tests/ppapi_example_audio/ppapi_example_audio.nmf new file mode 100644 index 0000000..2cdea3d --- /dev/null +++ b/ppapi/native_client/tests/ppapi_example_audio/ppapi_example_audio.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_example_audio_x86-32.nexe"}, + "x86-64": {"url": "ppapi_example_audio_x86-64.nexe"}, + "arm": {"url": "ppapi_example_audio_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_example_events/nacl.scons b/ppapi/native_client/tests/ppapi_example_events/nacl.scons new file mode 100644 index 0000000..36f4946 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_example_events/nacl.scons @@ -0,0 +1,21 @@ +# -*- python -*- +# 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. + +Import('env') + +# TODO(robertm): those should not be necessary once we go -std=c99 +env.FilterOut(CFLAGS=['-pedantic']) +env.FilterOut(CCFLAGS=['-pedantic']) + +nexe = 'ppapi_example_events_%s' % env.get('TARGET_FULLARCH') +env.Alias('ppapi_example_events${PROGSUFFIX}', + ['$STAGING_DIR/%s${PROGSUFFIX}' % nexe]) +ppapi_example_events_nexe = env.ComponentProgram(nexe, + ['ppapi_example_events.cc',], + EXTRA_LIBS=['${PPAPI_LIBS}', + 'ppapi_cpp']) +env.Publish(nexe, 'run', + ['ppapi_example_events.html', + 'ppapi_example_events.nmf']) diff --git a/ppapi/native_client/tests/ppapi_example_events/ppapi_example_events.cc b/ppapi/native_client/tests/ppapi_example_events/ppapi_example_events.cc new file mode 100644 index 0000000..fb18e71 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_example_events/ppapi_example_events.cc @@ -0,0 +1,210 @@ +// 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. + +// C headers +#include <cassert> +#include <cstdio> + +// C++ headers +#include <sstream> +#include <string> + +// NaCl +#include "ppapi/cpp/input_event.h" +#include "ppapi/cpp/instance.h" +#include "ppapi/cpp/module.h" +#include "ppapi/cpp/point.h" +#include "ppapi/cpp/var.h" + +namespace { +const char* const kEventsPropertyName = "events"; + +// Convert a given modifier to a descriptive string. Note that the actual +// declared type of modifier in each of the event classes is uint32_t, but it is +// expected to be interpreted as a bitfield of 'or'ed PP_InputEvent_Modifier +// values. +std::string ModifierToString(uint32_t modifier) { + std::string s; + if (modifier & PP_INPUTEVENT_MODIFIER_SHIFTKEY) { + s += "shift "; + } + if (modifier & PP_INPUTEVENT_MODIFIER_CONTROLKEY) { + s += "ctrl "; + } + if (modifier & PP_INPUTEVENT_MODIFIER_ALTKEY) { + s += "alt "; + } + if (modifier & PP_INPUTEVENT_MODIFIER_METAKEY) { + s += "meta "; + } + if (modifier & PP_INPUTEVENT_MODIFIER_ISKEYPAD) { + s += "keypad "; + } + if (modifier & PP_INPUTEVENT_MODIFIER_ISAUTOREPEAT) { + s += "autorepeat "; + } + if (modifier & PP_INPUTEVENT_MODIFIER_LEFTBUTTONDOWN) { + s += "left-button-down "; + } + if (modifier & PP_INPUTEVENT_MODIFIER_MIDDLEBUTTONDOWN) { + s += "middle-button-down "; + } + if (modifier & PP_INPUTEVENT_MODIFIER_RIGHTBUTTONDOWN) { + s += "right-button-down "; + } + if (modifier & PP_INPUTEVENT_MODIFIER_CAPSLOCKKEY) { + s += "caps-lock "; + } + if (modifier & PP_INPUTEVENT_MODIFIER_NUMLOCKKEY) { + s += "num-lock "; + } + return s; +} + +std::string MouseButtonToString(PP_InputEvent_MouseButton button) { + switch (button) { + case PP_INPUTEVENT_MOUSEBUTTON_NONE: + return "None"; + case PP_INPUTEVENT_MOUSEBUTTON_LEFT: + return "Left"; + case PP_INPUTEVENT_MOUSEBUTTON_MIDDLE: + return "Middle"; + case PP_INPUTEVENT_MOUSEBUTTON_RIGHT: + return "Right"; + default: + std::ostringstream stream; + stream << "Unrecognized (" + << static_cast<int32_t>(button) + << ")"; + return stream.str(); + } +} + +} // namespace + +class EventInstance : public pp::Instance { + public: + explicit EventInstance(PP_Instance instance) + : pp::Instance(instance) { + std::printf("EventInstance created.\n"); + RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE | PP_INPUTEVENT_CLASS_WHEEL); + RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_KEYBOARD); + } + virtual ~EventInstance() {} + + void GotKeyEvent(const pp::KeyboardInputEvent& key_event, + const std::string& kind) { + std::ostringstream stream; + stream << pp_instance() << ":" + << " Key event:" << kind + << " modifier:" << ModifierToString(key_event.GetModifiers()) + << " key_code:" << key_event.GetKeyCode() + << " time:" << key_event.GetTimeStamp() + << " text:" << key_event.GetCharacterText().DebugString() + << "\n"; + std::printf("%s", stream.str().c_str()); + PostMessage(stream.str()); + } + + void GotMouseEvent(const pp::MouseInputEvent& mouse_event, + const std::string& kind) { + std::ostringstream stream; + stream << pp_instance() << ":" + << " Mouse event:" << kind + << " modifier:" << ModifierToString(mouse_event.GetModifiers()) + << " button:" << MouseButtonToString(mouse_event.GetButton()) + << " x:" << mouse_event.GetPosition().x() + << " y:" << mouse_event.GetPosition().y() + << " click_count:" << mouse_event.GetClickCount() + << " time:" << mouse_event.GetTimeStamp() + << "\n"; + std::printf("%s", stream.str().c_str()); + PostMessage(stream.str()); + } + + void GotWheelEvent(const pp::WheelInputEvent& wheel_event) { + std::ostringstream stream; + stream << pp_instance() << ": Wheel event." + << " modifier:" << ModifierToString(wheel_event.GetModifiers()) + << " deltax:" << wheel_event.GetDelta().x() + << " deltay:" << wheel_event.GetDelta().y() + << " wheel_ticks_x:" << wheel_event.GetTicks().x() + << " wheel_ticks_y:" << wheel_event.GetTicks().y() + << " scroll_by_page:" + << (wheel_event.GetScrollByPage() ? "true" : "false") + << "\n"; + std::printf("%s", stream.str().c_str()); + PostMessage(stream.str()); + } + + // Handle an incoming input event by switching on type and dispatching + // to the appropriate subtype handler. + virtual bool HandleInputEvent(const pp::InputEvent& event) { + std::printf("HandleInputEvent called\n"); + switch (event.GetType()) { + case PP_INPUTEVENT_TYPE_UNDEFINED: + std::printf("Undefined event.\n"); + break; + case PP_INPUTEVENT_TYPE_MOUSEDOWN: + GotMouseEvent(pp::MouseInputEvent(event), "Down"); + break; + case PP_INPUTEVENT_TYPE_MOUSEUP: + GotMouseEvent(pp::MouseInputEvent(event), "Up"); + break; + case PP_INPUTEVENT_TYPE_MOUSEMOVE: + GotMouseEvent(pp::MouseInputEvent(event), "Move"); + break; + case PP_INPUTEVENT_TYPE_MOUSEENTER: + GotMouseEvent(pp::MouseInputEvent(event), "Enter"); + break; + case PP_INPUTEVENT_TYPE_MOUSELEAVE: + GotMouseEvent(pp::MouseInputEvent(event), "Leave"); + break; + case PP_INPUTEVENT_TYPE_WHEEL: + GotWheelEvent(pp::WheelInputEvent(event)); + break; + case PP_INPUTEVENT_TYPE_RAWKEYDOWN: + GotKeyEvent(pp::KeyboardInputEvent(event), "RawKeyDown"); + break; + case PP_INPUTEVENT_TYPE_KEYDOWN: + GotKeyEvent(pp::KeyboardInputEvent(event), "Down"); + break; + case PP_INPUTEVENT_TYPE_KEYUP: + GotKeyEvent(pp::KeyboardInputEvent(event), "Up"); + break; + case PP_INPUTEVENT_TYPE_CHAR: + GotKeyEvent(pp::KeyboardInputEvent(event), "Character"); + break; + default: + std::printf("Unrecognized event type: %d\n", event.GetType()); + assert(false); + return false; + } + return true; + } +}; + +// The EventModule provides an implementation of pp::Module that creates +// EventInstance objects when invoked. This is part of the glue code that makes +// our example accessible to ppapi. +class EventModule : public pp::Module { + public: + EventModule() : pp::Module() {} + virtual ~EventModule() {} + + virtual pp::Instance* CreateInstance(PP_Instance instance) { + std::printf("Creating EventInstance.\n"); + return new EventInstance(instance); + } +}; + +// Implement the required pp::CreateModule function that creates our specific +// kind of Module (in this case, EventModule). This is part of the glue code +// that makes our example accessible to ppapi. +namespace pp { + Module* CreateModule() { + std::printf("Creating EventModule.\n"); + return new EventModule(); + } +} diff --git a/ppapi/native_client/tests/ppapi_example_events/ppapi_example_events.html b/ppapi/native_client/tests/ppapi_example_events/ppapi_example_events.html new file mode 100644 index 0000000..501e91c --- /dev/null +++ b/ppapi/native_client/tests/ppapi_example_events/ppapi_example_events.html @@ -0,0 +1,67 @@ +<!DOCTYPE html> +<html> + <!-- + 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. + --> +<head> + <title>PPAPI InputEvent test</title> + + <script type="text/javascript"> + function $(id) { + return document.getElementById(id); + } + + var events = ''; + + function receiveMessage(message) { + events += message.data; + } + + function getEvents() { + try { + var event_dump = $('event_dump'); + event_dump.firstChild.nodeValue = events; + events = ''; + } catch(e) { + alert(e.message); + } + } + </script> +</head> +<body> +<h1>InputEvent Handling Example</h1> + <div id="listener"> + <script type="text/javascript"> + $('listener').addEventListener('message', receiveMessage, true); + </script> + + <embed name="nacl_module" + id="event_module" + width=400 height=400 + src="ppapi_example_events.nmf" + type="application/x-nacl" + style="background-color:gray" /> + </div> +<p> +This example demonstrates handling of input events in PPAPI. +<p> +Each time an input event happens in the context of the gray box, +the embedded NaCl module prints a message describing the event to the shell +where you started your Browser. +<p> +Alternatively, you can click the "Get Events" button to display +all input events that have happened since the last time you clicked the +button. +</p> +<form name="event_form" action="" method="get"> + <input type="button" value="Get Events" onclick="getEvents()"/> +</form> + +<h2>Recent Events (press button to update):</h2> +<pre id=event_dump> +no events +</pre> +</body> +</html> diff --git a/ppapi/native_client/tests/ppapi_example_events/ppapi_example_events.nmf b/ppapi/native_client/tests/ppapi_example_events/ppapi_example_events.nmf new file mode 100644 index 0000000..902e4457 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_example_events/ppapi_example_events.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_example_events_x86-32.nexe"}, + "x86-64": {"url": "ppapi_example_events_x86-64.nexe"}, + "arm": {"url": "ppapi_example_events_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_example_font/nacl.scons b/ppapi/native_client/tests/ppapi_example_font/nacl.scons new file mode 100644 index 0000000..3143ab3d --- /dev/null +++ b/ppapi/native_client/tests/ppapi_example_font/nacl.scons @@ -0,0 +1,36 @@ +# -*- python -*- +# 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. + +# This is a Pepper font example from ppapi/examples/font. + +Import('env') + +env.Prepend(CPPDEFINES=['XP_UNIX']) + +# Adjust compiler flags to the more forgiving standards used in +# ppapi/examples/*. +env.FilterOut(CCFLAGS=['-Werror', '-pedantic']) +env.Append(CCFLAGS=['-Wformat=0']) + +nexe_name = 'ppapi_example_font_${TARGET_FULLARCH}' +obj = env.ComponentObject( + 'simple_font', + '$SOURCE_ROOT/ppapi/examples/font/simple_font.cc' + ) +nexe = env.ComponentProgram(nexe_name, [obj], + EXTRA_LIBS=['${PPAPI_LIBS}', 'ppapi_cpp']) + +# Note that the html is required to run this program. +env.Publish(nexe_name, 'run', + ['ppapi_example_font.html', 'ppapi_example_font.nmf']) + +test = env.PPAPIBrowserTester('ppapi_example_font_test.out', + url='ppapi_example_font.html', + files=env.ExtractPublishedFiles(nexe_name)) + +env.AddNodeToTestSuite(test, + ['chrome_browser_tests'], + 'run_ppapi_example_font_test', + is_broken=env.PPAPIBrowserTesterIsBroken()) diff --git a/ppapi/native_client/tests/ppapi_example_font/ppapi_example_font.html b/ppapi/native_client/tests/ppapi_example_font/ppapi_example_font.html new file mode 100644 index 0000000..25bd6d12 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_example_font/ppapi_example_font.html @@ -0,0 +1,49 @@ +<!-- + Copyright 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. +--> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> + <head> + <meta http-equiv="Pragma" content="no-cache" /> + <meta http-equiv="Expires" content="-1" /> + <script type="text/javascript" src="nacltest.js"></script> + <title>Native Client PPAPI Font Example</title> + </head> + + <body> + <h1>Native Client PPAPI Font Example</h1> + <div> + <embed id="naclModule" + name="naclModule" + width=400 height=400 + src="ppapi_example_font.nmf" + basic_tests="1" + stress_tests="0" + style="background-color:gray" + type="application/x-nacl" /> + </div> + <p>The example works if you see (a) large Arabic script and (b) 4 font + samples (default, serif, sans serif, and monospace) + + <script type="text/javascript"> + //<![CDATA[ +function setupTests(tester, plugin) { + // The PPAPI font examples does all its work in DidChangeView, so we just + // verify that it loaded successfully by inserting a dummy test. + // This only tests that DidChangeView completed successfully; we have no + // automated way of checking that it actually plotted the fonts. + tester.addAsyncTest('DummyTestToEnsureThatModuleCompletedLoading', + function(status) { status.pass(); }); +} + +var tester = new Tester(); +setupTests(tester, $('naclModule')); +tester.waitFor($('naclModule')); +tester.run(); + //]]> + </script> + </body> +</html> diff --git a/ppapi/native_client/tests/ppapi_example_font/ppapi_example_font.nmf b/ppapi/native_client/tests/ppapi_example_font/ppapi_example_font.nmf new file mode 100644 index 0000000..4757f79 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_example_font/ppapi_example_font.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_example_font_x86-32.nexe"}, + "x86-64": {"url": "ppapi_example_font_x86-64.nexe"}, + "arm": {"url": "ppapi_example_font_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_example_gles2/nacl.scons b/ppapi/native_client/tests/ppapi_example_gles2/nacl.scons new file mode 100644 index 0000000..ed0cc47 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_example_gles2/nacl.scons @@ -0,0 +1,37 @@ +# -*- python -*- +# 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. + +# This is a Pepper 3D (OpenGLES2) example from ppapi/examples/gles2. + +Import('env') + +env.Prepend(CPPDEFINES=['XP_UNIX']) + +env.Append(CPPPATH=['$SOURCE_ROOT/ppapi/lib/gl/include']) + +nexe_name = 'ppapi_example_gles2_%s' % env.get('TARGET_FULLARCH') +obj = env.ComponentObject( + 'gles2', + '$SOURCE_ROOT/ppapi/examples/gles2/gles2.cc' + ) +nexe = env.ComponentProgram(nexe_name, [obj], + EXTRA_LIBS=['${PPAPI_LIBS}', 'ppapi_cpp']) + +# Note that the html is required to run this program. +env.Publish(nexe_name, 'run', + ['ppapi_example_gles2.html', 'ppapi_example_gles2.nmf']) + +test = env.PPAPIBrowserTester('ppapi_example_gles2_test.out', + url='ppapi_example_gles2.html', + files=env.ExtractPublishedFiles(nexe_name), + args=['--enable_experimental_js']) + +env.AddNodeToTestSuite(test, + ['chrome_browser_tests'], + 'run_ppapi_example_gles2_test', + # TODO(cstefansen): When fixed set to + # env.PPAPIBrowserTesterIsBroken(). + # code.google.com/p/nativeclient/issues/detail?id=1936 + is_broken=True) diff --git a/ppapi/native_client/tests/ppapi_example_gles2/ppapi_example_gles2.html b/ppapi/native_client/tests/ppapi_example_gles2/ppapi_example_gles2.html new file mode 100644 index 0000000..8fe4f5f --- /dev/null +++ b/ppapi/native_client/tests/ppapi_example_gles2/ppapi_example_gles2.html @@ -0,0 +1,51 @@ +<!-- + Copyright 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. +--> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + <head> + <meta http-equiv="Pragma" content="no-cache" /> + <meta http-equiv="Expires" content="-1" /> + <script type="text/javascript" src="nacltest.js"></script> + <title>Native Client PPAPI Graphics3D (OpenGL ES)</title> + </head> + + <body> + <h1>Native Client PPAPI Graphics3D (OpenGL ES)</h1> + <div> + <embed id="naclModule" + name="naclModule" + width=400 height=400 + src="ppapi_example_gles2.nmf" + basic_tests="1" + stress_tests="0" + style="background-color:gray" + type="application/x-nacl" /> + </div> + <p>The example works if you see a square flickering between red and + blue above. Note that the automated test only verifies that the + NaCl module loaded. It cannot and does not verify that the visual + output is correct. + + <script type="text/javascript"> + //<![CDATA[ +function setupTests(tester, plugin) { + // The PPAPI font examples does all its work in DidChangeView, so we just + // verify that it loaded successfully by inserting a dummy test. + // This only tests that DidChangeView completed successfully; we have no + // automated way of checking that it actually plotted the fonts. + tester.addAsyncTest('DummyTestToEnsureThatModuleCompletedLoading', + function(status) { status.pass(); }); +} + +var tester = new Tester(); +setupTests(tester, $('naclModule')); +tester.waitFor($('naclModule')); +tester.run(); + //]]> + </script> + </body> +</html>
\ No newline at end of file diff --git a/ppapi/native_client/tests/ppapi_example_gles2/ppapi_example_gles2.nmf b/ppapi/native_client/tests/ppapi_example_gles2/ppapi_example_gles2.nmf new file mode 100644 index 0000000..3f5ebe8 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_example_gles2/ppapi_example_gles2.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_example_gles2_x86-32.nexe"}, + "x86-64": {"url": "ppapi_example_gles2_x86-64.nexe"}, + "arm": {"url": "ppapi_example_gles2_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_example_post_message/nacl.scons b/ppapi/native_client/tests/ppapi_example_post_message/nacl.scons new file mode 100644 index 0000000..bb30dc7 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_example_post_message/nacl.scons @@ -0,0 +1,34 @@ +# -*- python -*- +# 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. + +# This is a Pepper PostMessage example from ppapi/examples/scripting. + +Import('env') + +env.Prepend(CPPDEFINES=['XP_UNIX']) + +nexe_name = 'ppapi_example_post_message_${TARGET_FULLARCH}' +obj = env.ComponentObject( + 'post_message', + '$SOURCE_ROOT/ppapi/examples/scripting/post_message.cc' + ) +nexe = env.ComponentProgram(nexe_name, [obj], + EXTRA_LIBS=['${PPAPI_LIBS}', 'ppapi_cpp']) + +# Note that the html is required to run this program. +env.Publish(nexe_name, 'run', + ['ppapi_example_post_message.html', + 'ppapi_example_post_message.nmf']) + + +test = env.PPAPIBrowserTester( + 'ppapi_example_post_message_test.out', + url='ppapi_example_post_message.html', + files=env.ExtractPublishedFiles(nexe_name)) + +env.AddNodeToTestSuite(test, + ['chrome_browser_tests'], + 'run_ppapi_example_post_message_test', + is_broken=env.PPAPIBrowserTesterIsBroken()) diff --git a/ppapi/native_client/tests/ppapi_example_post_message/ppapi_example_post_message.html b/ppapi/native_client/tests/ppapi_example_post_message/ppapi_example_post_message.html new file mode 100644 index 0000000..00e5ef2 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_example_post_message/ppapi_example_post_message.html @@ -0,0 +1,60 @@ +<!-- + Copyright 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. +--> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + <head> + <meta http-equiv="Pragma" content="no-cache" /> + <meta http-equiv="Expires" content="-1" /> + <script type="text/javascript" src="nacltest.js"></script> + <title>Native Client PPAPI Post Message Example</title> + </head> + + <body> + <h1>Native Client PPAPI Post Message Example</h1> + <div> + <embed id="naclModule" + name="naclModule" + width=400 height=400 + src="ppapi_example_post_message.nmf" + basic_tests="2" + stress_tests="0" + style="background-color:gray" + type="application/x-nacl" /> + </div> + + <script type="text/javascript"> + //<![CDATA[ +function setupTests(tester, plugin) { + tester.addAsyncTest('TestPalindrome', function(status) { + // Try posting a palindrome to the plugin. + plugin.addEventListener('message', function(message_event) { + this.removeEventListener('message', arguments.callee, false); + status.assertEqual(message_event.data, true); + status.pass(); + }, false); + plugin.postMessage('amokigleredderelgikoma'); + }); + + tester.addAsyncTest('TestNonPalindrome', function(status) { + // Try posting a non-palindrome. + plugin.addEventListener('message', function(message_event) { + this.removeEventListener('message', arguments.callee, false); + status.assertEqual(message_event.data, false); + status.pass(); + }, false); + plugin.postMessage('This is not a palindrome.'); + }); +} + +var tester = new Tester(); +setupTests(tester, $('naclModule')); +tester.waitFor($('naclModule')); +tester.run(); + //]]> + </script> + </body> +</html> diff --git a/ppapi/native_client/tests/ppapi_example_post_message/ppapi_example_post_message.nmf b/ppapi/native_client/tests/ppapi_example_post_message/ppapi_example_post_message.nmf new file mode 100644 index 0000000..0dafadf --- /dev/null +++ b/ppapi/native_client/tests/ppapi_example_post_message/ppapi_example_post_message.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_example_post_message_x86-32.nexe"}, + "x86-64": {"url": "ppapi_example_post_message_x86-64.nexe"}, + "arm": {"url": "ppapi_example_post_message_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_geturl/build.scons b/ppapi/native_client/tests/ppapi_geturl/build.scons new file mode 100644 index 0000000..8baaa1c --- /dev/null +++ b/ppapi/native_client/tests/ppapi_geturl/build.scons @@ -0,0 +1,33 @@ +# -*- python -*- +# 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. + +# A way to build the nexe as a trusted plugin to validate directly +# against Chrome on Linux using +# --register-pepper-plugins="/path/to/libppapi_geturl.so;application/x-nacl" +# http://localhost:5103/scons-out/nacl-x86-../staging/ppapi_geturl.html + +Import('env') + +if env.Bit('linux'): + env['COMPONENT_STATIC'] = False # Build a .so, not a .a + + sources = [ 'module.cc', + # This allow us to verify that the code builds before + # untrusted nacl_file is fully functioning. + # However, main() won't be called when we loaded the trusted + # plugin as a dll. + 'nacl_file_main.cc', + 'ppapi_geturl.cc', + 'url_load_request.cc' ] + + libs = [ 'ppapi_cpp', + 'imc', + 'gio', + 'pthread' ] + + ppapi_geturl = env.ComponentLibrary('ppapi_geturl', + sources, + EXTRA_LIBS=libs, + no_import_lib=True) diff --git a/ppapi/native_client/tests/ppapi_geturl/module.cc b/ppapi/native_client/tests/ppapi_geturl/module.cc new file mode 100644 index 0000000..ad953b5 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_geturl/module.cc @@ -0,0 +1,323 @@ +// 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/tests/ppapi_geturl/module.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <string> + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/src/untrusted/ppapi/nacl_file.h" +#include "native_client/tests/ppapi_geturl/nacl_file_main.h" +#include "native_client/tests/ppapi_geturl/url_load_request.h" + +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_var.h" +#include "ppapi/c/ppp_instance.h" +#include "ppapi/c/ppp_messaging.h" + +#if !defined(__native_client__) +int32_t LoadUrl(PP_Instance /*instance*/, const char* /*url*/, + PP_CompletionCallback /*callback*/) { return PP_OK; } +#endif + +namespace { + +// These constants need to match their corresponding JavaScript values in +// ppapi_geturl.html. The JavaScript variables are all upper-case; for example +// kTrueStringValue corresponds to TRUE_STRING_VALUE. +const char* const kLoadUrlMethodId = "loadUrl"; +const char* const kTrueStringValue = "1"; +const char* const kFalseStringValue = "0"; +static const char kArgumentSeparator = '|'; + +// A helper function to convert a bool to a string, used when assembling +// messages posted back to the browser. |true| is converted to "1", |false| to +// "0". +const std::string BoolToString(bool bool_value) { + return bool_value ? kTrueStringValue : kFalseStringValue; +} + +PPP_Instance instance_interface; +PPP_Messaging messaging_interface; +Module* singleton_ = NULL; + +void RunTests(void* user_data) { + int* count = reinterpret_cast<int*>(user_data); + *count -= 1; + if (*count == 0) + test_nacl_file(); +} +} // namespace + +void HTMLLoaded(void* user_data, int32_t result) { + CHECK(PP_OK == result); + printf("--- HTMLLoaded() SUCCESS: completion callback got PP_OK\n"); + RunTests(user_data); +} + +void RobotLoaded(void* user_data, int32_t result) { + CHECK(PP_ERROR_NOACCESS == result); + printf("--- RobotLoaded() SUCCESS: unable to LoadUrl on cross-domain\n"); + RunTests(user_data); +} + +void NonExistLoaded(void* user_data, int32_t result) { + CHECK(PP_ERROR_FAILED == result); + printf("--- NonExistLoaded() SUCCESS: callback got PP_ERROR_FAILED\n"); + RunTests(user_data); +} + +PP_Bool Instance_DidCreate(PP_Instance pp_instance, + uint32_t /*argc*/, + const char* /*argn*/[], + const char* /*argv*/[]) { + printf("--- Instance_DidCreate\n"); + int* url_count = new int(3); + PP_CompletionCallback html_cb = + PP_MakeCompletionCallback(HTMLLoaded, url_count); + int32_t result = LoadUrl(pp_instance, "ppapi_geturl_success.html", html_cb); + + PP_CompletionCallback robot_cb = + PP_MakeCompletionCallback(RobotLoaded, url_count); + result = LoadUrl(pp_instance, "http://www.google.com/robots.txt", robot_cb); + + PP_CompletionCallback non_exist_cb = + PP_MakeCompletionCallback(NonExistLoaded, url_count); + result = LoadUrl(pp_instance, "ppapi_nonexistent_url.html", non_exist_cb); + + return PP_TRUE; +} + +void Instance_DidDestroy(PP_Instance /*instance*/) { + printf("--- Instance_DidDestroy\n"); +} + +void Instance_DidChangeView(PP_Instance /*pp_instance*/, + const PP_Rect* /*position*/, + const PP_Rect* /*clip*/) { +} + +void Instance_DidChangeFocus(PP_Instance /*pp_instance*/, + PP_Bool /*has_focus*/) { +} + +PP_Bool Instance_HandleDocumentLoad(PP_Instance /*pp_instance*/, + PP_Resource /*pp_url_loader*/) { + return PP_FALSE; +} + +void Messaging_HandleMessage(PP_Instance instance, struct PP_Var var_message) { + if (var_message.type != PP_VARTYPE_STRING) + return; + std::string message = Module::Get()->VarToStr(var_message); + printf("--- Messaging_HandleMessage(%s)\n", message.c_str()); + // Look for the "loadUrl" message. The expected string format looks like: + // loadUrl|<url>|<stream_as_file> + // loadUrl is a string literal + // <url> is the URL used to make the GET request in UrlLoader + // <stream_as_file> represent Boolean true if it's a '1' or false if it's + // anything else. + if (message.find(kLoadUrlMethodId) != 0) + return; + + size_t url_pos = message.find_first_of(kArgumentSeparator); + if (url_pos == std::string::npos || url_pos + 1 >= message.length()) + return; + + size_t as_file_pos = message.find_first_of(kArgumentSeparator, url_pos + 1); + if (as_file_pos == std::string::npos || as_file_pos + 1 >= message.length()) + return; + + size_t url_length = as_file_pos - url_pos; + if (url_length == 0) + return; + std::string url = message.substr(url_pos + 1, url_length - 1); + + // If the second argument is a '1', assume it means |stream_as_file| is + // true. Anything else means |stream_as_file| is false. + bool stream_as_file = message.compare(as_file_pos + 1, + 1, + kTrueStringValue) == 0; + + printf("--- Messaging_HandleMessage(method='%s', " + "url='%s', " + "stream_as_file='%s')\n", + message.c_str(), + url.c_str(), + stream_as_file ? "true" : "false"); + fflush(stdout); + + UrlLoadRequest* url_load_request = new UrlLoadRequest(instance); + if (NULL == url_load_request) { + Module::Get()->ReportResult(instance, + url.c_str(), + stream_as_file, + "LoadUrl: memory allocation failed", + false); + return; + } + // On success or failure url_load_request will call ReportResult(). + // This is the time to clean it up. + url_load_request->set_delete_this_after_report(); + url_load_request->Load(stream_as_file, url); +} + +Module* Module::Create(PP_Module module_id, + PPB_GetInterface get_browser_interface) { + if (NULL == singleton_) { + singleton_ = new Module(module_id, get_browser_interface); + } + return singleton_; +} + +Module* Module::Get() { + return singleton_; +} + +void Module::Free() { + delete singleton_; + singleton_ = NULL; +} + +Module::Module(PP_Module module_id, PPB_GetInterface get_browser_interface) + : module_id_(module_id), + get_browser_interface_(get_browser_interface), + ppb_core_interface_(NULL), + ppb_messaging_interface_(NULL), + ppb_var_interface_(NULL) { + printf("--- Module::Module\n"); + memset(&instance_interface, 0, sizeof(instance_interface)); + instance_interface.DidCreate = Instance_DidCreate; + instance_interface.DidDestroy = Instance_DidDestroy; + instance_interface.DidChangeView = Instance_DidChangeView; + instance_interface.DidChangeFocus = Instance_DidChangeFocus; + instance_interface.HandleDocumentLoad = Instance_HandleDocumentLoad; + + memset(&messaging_interface, 0, sizeof(messaging_interface)); + messaging_interface.HandleMessage = Messaging_HandleMessage; + + ppb_core_interface_ = + static_cast<const PPB_Core*>( + GetBrowserInterface(PPB_CORE_INTERFACE)); + ppb_messaging_interface_ = + static_cast<const PPB_Messaging*>( + GetBrowserInterface(PPB_MESSAGING_INTERFACE)); + ppb_var_interface_ = + static_cast<const PPB_Var*>( + GetBrowserInterface(PPB_VAR_INTERFACE)); +} + +const void* Module::GetPluginInterface(const char* interface_name) { + printf("--- Module::GetPluginInterface(%s)\n", interface_name); + if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0) + return &instance_interface; + if (strcmp(interface_name, PPP_MESSAGING_INTERFACE) == 0) + return &messaging_interface; + return NULL; +} + +const void* Module::GetBrowserInterface(const char* interface_name) { + if (NULL == get_browser_interface_) + return NULL; + return (*get_browser_interface_)(interface_name); +} + +char* Module::VarToCStr(const PP_Var& var) { + Module* module = Get(); + if (NULL == module) + return NULL; + const PPB_Var* ppb_var = module->ppb_var_interface(); + if (NULL == ppb_var) + return NULL; + uint32_t len = 0; + const char* pp_str = ppb_var->VarToUtf8(var, &len); + if (NULL == pp_str) + return NULL; + char* str = static_cast<char*>(malloc(len + 1)); + if (NULL == str) + return NULL; + memcpy(str, pp_str, len); + str[len] = 0; + return str; +} + +std::string Module::VarToStr(const PP_Var& var) { + std::string str; + char* cstr = VarToCStr(var); + if (NULL != cstr) { + str = cstr; + free(cstr); + } + return str; +} + +PP_Var Module::StrToVar(const char* str) { + Module* module = Get(); + if (NULL == module) + return PP_MakeUndefined(); + const PPB_Var* ppb_var = module->ppb_var_interface(); + if (NULL != ppb_var) + return ppb_var->VarFromUtf8(module->module_id(), str, strlen(str)); + return PP_MakeUndefined(); +} + +PP_Var Module::StrToVar(const std::string& str) { + return Module::StrToVar(str.c_str()); +} + +std::string Module::ErrorCodeToStr(int32_t error_code) { + switch (error_code) { + case PP_OK: return "PP_OK"; + case PP_OK_COMPLETIONPENDING: return "PP_OK_COMPLETIONPENDING"; + case PP_ERROR_FAILED: return "PP_ERROR_FAILED"; + case PP_ERROR_ABORTED: return "PP_ERROR_ABORTED"; + case PP_ERROR_BADARGUMENT: return "PP_ERROR_BADARGUMENT"; + case PP_ERROR_BADRESOURCE: return "PP_ERROR_BADRESOURCE"; + case PP_ERROR_NOINTERFACE: return "PP_ERROR_NOINTERFACE"; + case PP_ERROR_NOACCESS: return "PP_ERROR_NOACCESS"; + case PP_ERROR_NOMEMORY: return "PP_ERROR_NOMEMORY"; + case PP_ERROR_NOSPACE: return "PP_ERROR_NOSPACE"; + case PP_ERROR_NOQUOTA: return "PP_ERROR_NOQUOTA"; + case PP_ERROR_INPROGRESS: return "PP_ERROR_INPROGRESS"; + case PP_ERROR_FILENOTFOUND: return "PP_ERROR_FILENOTFOUND"; + case PP_ERROR_FILEEXISTS: return "PP_ERROR_FILEEXISTS"; + case PP_ERROR_FILETOOBIG: return "PP_ERROR_FILETOOBIG"; + case PP_ERROR_FILECHANGED: return "PP_ERROR_FILECHANGED"; + case PP_ERROR_TIMEDOUT: return "PP_ERROR_TIMEDOUT"; + } + return "N/A"; +} + +void Module::ReportResult(PP_Instance pp_instance, + const char* url, + bool as_file, + const char* text, + bool success) { + printf("--- ReportResult('%s', as_file=%d, '%s', success=%d)\n", + url, as_file, text, success); + // Post a message with the results back to the browser. + std::string result(url); + result += kArgumentSeparator; + result += BoolToString(as_file); + result += kArgumentSeparator; + result += text; + result += kArgumentSeparator; + result += BoolToString(success); + printf("--- ReportResult posts result string:\n\t%s\n", result.c_str()); + struct PP_Var var_result = StrToVar(result); + ppb_messaging_interface()->PostMessage(pp_instance, var_result); + // If the message was created using VarFromUtf8() it needs to be released. + // See the comments about VarFromUtf8() in ppapi/c/ppb_var.h for more + // information. + if (var_result.type == PP_VARTYPE_STRING) { + ppb_var_interface()->Release(var_result); + } +} diff --git a/ppapi/native_client/tests/ppapi_geturl/module.h b/ppapi/native_client/tests/ppapi_geturl/module.h new file mode 100644 index 0000000..7b526d2 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_geturl/module.h @@ -0,0 +1,62 @@ +// 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. +#ifndef TESTS_PPAPI_GETURL_MODULE_H_ +#define TESTS_PPAPI_GETURL_MODULE_H_ + +#include <string> + +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/ppb.h" +#include "ppapi/c/ppb_core.h" +#include "ppapi/c/ppb_messaging.h" +#include "ppapi/c/ppb_var.h" +#include "ppapi/c/ppp.h" + +// ppapi_geturl example is deliberately using C PPAPI interface. +// C++ PPAPI layer has pp::Module wrapper class. +class Module { + public: + static Module* Create(PP_Module module_id, + PPB_GetInterface get_browser_interface); + static Module* Get(); + static void Free(); + + const void* GetPluginInterface(const char* interface_name); + const void* GetBrowserInterface(const char* interface_name); + PP_Module module_id() { return module_id_; } + const PPB_Core* ppb_core_interface() const { return ppb_core_interface_; } + const PPB_Messaging* ppb_messaging_interface() const { + return ppb_messaging_interface_; + } + const PPB_Var* ppb_var_interface() const { return ppb_var_interface_; } + + static char* VarToCStr(const PP_Var& var); + static std::string VarToStr(const PP_Var& var); + static PP_Var StrToVar(const char* str); + static PP_Var StrToVar(const std::string& str); + static std::string ErrorCodeToStr(int32_t error_code); + + // Constructs a parameterized message string then uses messaging.PostMessage + // to send this message back to the browser. The receiving message handler + // is defined in ppapi_geturl.html + void ReportResult(PP_Instance pp_instance, + const char* url, + bool as_file, + const char* text, + bool success); + private: + PP_Module module_id_; + PPB_GetInterface get_browser_interface_; + const PPB_Core* ppb_core_interface_; + const PPB_Messaging* ppb_messaging_interface_; + const PPB_Var* ppb_var_interface_; + + Module(PP_Module module_id, PPB_GetInterface get_browser_interface); + ~Module() { } + Module(const Module&); + void operator=(const Module&); +}; + +#endif // TESTS_PPAPI_GETURL_MODULE_H_ diff --git a/ppapi/native_client/tests/ppapi_geturl/nacl.scons b/ppapi/native_client/tests/ppapi_geturl/nacl.scons new file mode 100644 index 0000000..26078bc --- /dev/null +++ b/ppapi/native_client/tests/ppapi_geturl/nacl.scons @@ -0,0 +1,62 @@ +# -*- python -*- +# 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. + +# This is a C PPAPI-based version of ../npapi_geturl. +# +# ppapi_geturl.html - test driver that loads the nexe and scripts it +# ppapi_geturl_success.html - to be url-loaded and displayed w/n driver html +# +# ppapi_geturl.cc - implementation of PPP interface +# module.h/cc - implementation of PPP_Instance interface +# scriptable_object.h/cc - implementation of the scripting interface +# url_load_request.h/cc - url loading helper +# nacl_file_main.cc - uses main() to test NaClFile interface + +Import('env') + +env.Prepend(CPPDEFINES=['XP_UNIX']) + +nexe = 'ppapi_geturl_%s' % env.get('TARGET_FULLARCH') +env.Alias('ppapi_geturl${PROGSUFFIX}', + ['$STAGING_DIR/%s${PROGSUFFIX}' % nexe]) + +ppapi_geturl_nexe = env.ComponentProgram(nexe, + ['nacl_file_main.cc', + 'module.cc', + 'ppapi_geturl.cc', + 'url_load_request.cc', + ], + EXTRA_LIBS=[ + 'nacl_file', + 'ppruntime', + 'srpc', + 'imc', + 'imc_syscalls', + 'platform', + 'gio', + '${PTHREAD_LIBS}', + 'm', + '${NON_PPAPI_BROWSER_LIBS}'], + EXTRA_LINKFLAGS=['-Wl,--wrap=read', + '-Wl,--wrap=open', + '-Wl,--wrap=lseek', + '-Wl,--wrap=close']) + +env.Publish(nexe, 'run', + ['ppapi_geturl.html', + 'ppapi_geturl.nmf', + 'ppapi_geturl_success.html']) + +node = env.PPAPIBrowserTester('ppapi_geturl_browser_test.out', + url='ppapi_geturl.html', + files=env.ExtractPublishedFiles(nexe), + args=['--allow_404'], + ) + +env.AddNodeToTestSuite(node, + ['chrome_browser_tests'], + 'run_ppapi_geturl_browser_test', + is_broken=env.PPAPIBrowserTesterIsBroken() + ) diff --git a/ppapi/native_client/tests/ppapi_geturl/nacl_file_main.cc b/ppapi/native_client/tests/ppapi_geturl/nacl_file_main.cc new file mode 100644 index 0000000..aaf922c --- /dev/null +++ b/ppapi/native_client/tests/ppapi_geturl/nacl_file_main.cc @@ -0,0 +1,214 @@ +// 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. +// +// Tests nacl_file library. +// + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <pthread.h> +#include <unistd.h> + +#include "native_client/src/include/nacl_base.h" +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/src/shared/ppapi_proxy/utility.h" +#include "native_client/src/untrusted/ppapi/nacl_file.h" + +using ppapi_proxy::DebugPrintf; + +struct ThreadInfo { + bool threaded; + unsigned int rseed; +}; + +// Open and read a valid existing file into a buffer. +// Return the number of bytes read. +int test_nacl_file_read_into_buffer(ThreadInfo* info, + int buffer_size, + char* buffer) { + // Valid url should be open and read without errors. + int fd = open("ppapi_geturl_success.html", O_RDONLY); + CHECK(fd >= 0); + int bytes_read = read(fd, buffer, buffer_size); + CHECK(215 == bytes_read); + CHECK(strstr(buffer, "TEST PASSED") == buffer); + close(fd); + if (!info->threaded) { + // This part of the test only works when run in a single thread. In a + // multi-threaded test, between the close (above) and read (below), another + // thread could recycle the fd. In a single threaded test, the read below + // should fail because the fd was just closed. + bytes_read = read(fd, buffer, buffer_size); + CHECK(-1 == bytes_read); + } + return bytes_read; +} + +// Open and read a valid existing file. +void test_nacl_file_basic_read(ThreadInfo* info) { + char buffer[256]; + test_nacl_file_read_into_buffer(info, sizeof(buffer), buffer); +} + +// Do some basic lseek tests on a valid file. +void test_nacl_file_basic_lseek() { + char buffer[256]; + // Some of these seeks are relative, and may depend on results of previous + // seeks. + int fd = open("ppapi_geturl_success.html", O_RDONLY); + CHECK(fd >= 0); + off_t start = lseek(fd, 0, SEEK_SET); + CHECK(0 == start); + off_t end = lseek(fd, 0, SEEK_END); + CHECK(end > 0); + off_t start2 = lseek(fd, -end, SEEK_CUR); + CHECK(0 == start2); + off_t end2 = lseek(fd, end, SEEK_CUR); + CHECK(end2 == end); + off_t end3 = lseek(fd, end, SEEK_SET); + CHECK(end3 == end); + off_t pos1 = lseek(fd, -2, SEEK_CUR); + off_t pos2 = lseek(fd, 0, SEEK_CUR); + CHECK(pos1 == pos2); + lseek(fd, 1, SEEK_CUR); + off_t end4 = lseek(fd, 1, SEEK_CUR); + CHECK(end4 == end); + off_t beyond = lseek(fd, 100, SEEK_END); + CHECK((end + 100) == beyond); + off_t invalid_offset = lseek(fd, -2, SEEK_SET); + CHECK(-1 == invalid_offset); + CHECK(EINVAL == errno); + off_t beyond2 = lseek(fd, 0, SEEK_CUR); + CHECK(beyond2 == beyond); + off_t badfd = lseek(1234567, 0, SEEK_SET); + CHECK(-1 == badfd); + CHECK(EBADF == errno); + // Seek back to start and try same read test again. + CHECK(lseek(fd, 0, SEEK_SET) == 0); + int bytes_read = read(fd, buffer, sizeof(buffer)); + CHECK(215 == bytes_read); + CHECK(strstr(buffer, "TEST PASSED") == buffer); + off_t off = lseek(fd, 0, SEEK_END); + CHECK(215 == off); + close(fd); +} + +// Briefly test the fopen() and friends interface built on top of lower- +// level open() and friends. +void test_nacl_file_fopen() { + FILE* f = fopen("ppapi_geturl_success.html", "r"); + CHECK(NULL != f); + char buffer[256]; + char* pbuffer = fgets(buffer, sizeof(buffer), f); + CHECK(pbuffer == buffer); + fclose(f); + int compare = strcmp(buffer, "TEST PASSED\n"); + CHECK(0 == compare); +} + +// Do a blizzard of small, random file operations. Randomly seek +// and read a byte many times, comparing the read result against the +// whole buffer that was read earlier. Do this against a random number of +// simultaniously temporarily open files. +void test_nacl_file_many_times(ThreadInfo* info) { + int bytes_read; + char buffer[256]; + bytes_read = test_nacl_file_read_into_buffer(info, sizeof(buffer), buffer); + const int kNumOuterLoop = 20; + const int kNumMaxFilesOpen = 10; + const int kNumRandomReads = 500; + for (int i = 0; i < kNumOuterLoop; ++i) { + int file[kNumMaxFilesOpen]; + int num_open = rand_r(&info->rseed) % (kNumMaxFilesOpen - 1) + 1; + CHECK(0 < num_open); + CHECK(kNumMaxFilesOpen > num_open); + for (int j = 0; j < num_open; ++j) { + file[j] = open("ppapi_geturl_success.html", O_RDONLY); + CHECK(-1 != file[j]); + } + int num_reads = rand_r(&info->rseed) % kNumRandomReads; + for (int k = 0; k < num_reads; ++k) { + char a_byte; + const int which_file = rand_r(&info->rseed) % num_open; + const int which_byte = rand_r(&info->rseed) % bytes_read; + int r = lseek(file[which_file], which_byte, SEEK_SET); + CHECK(which_byte == r); + size_t num_read = read(file[which_file], &a_byte, sizeof(a_byte)); + CHECK(1 == num_read); + CHECK(a_byte == buffer[which_byte]); + } + for (int j = 0; j < num_open; ++j) { + close(file[j]); + } + } +} + +// Test nacl_file library functions that override standard POSIX file I/O +// functions and are intended to have the same behavior. +void* test_nacl_file_thread(void* user_data) { + ThreadInfo* info = reinterpret_cast<ThreadInfo*>(user_data); + test_nacl_file_basic_read(info); + test_nacl_file_basic_lseek(); + test_nacl_file_basic_read(info); + // Cross origin url should fail on open. + int fd = open("http://www.google.com/robots.txt", O_RDONLY); + CHECK(-1 == fd); + // Invalid url should fail on open. + fd = open("doesnotexist.html", O_RDONLY); + CHECK(-1 == fd); +#if defined(__native_client__) + // Open for write should fail in NaCl. + int no_fd = open("ppapi_geturl_success.html", O_CREAT); + CHECK(-1 == no_fd); + CHECK(EACCES == errno); +#endif + test_nacl_file_fopen(); + test_nacl_file_many_times(info); + return NULL; +} + +// Main entry point to test nacl_file library. It is assumed that before calling +// this function, LoadUrl() has been invoked for each file to be tested, and +// that the completion callback has been reached. +void test_nacl_file() { + const char *nacl_enable_ppapi_dev = getenv("NACL_ENABLE_PPAPI_DEV"); + int enabled = 0; + // Skip test if NACL_ENABLE_PPAPI_DEV is unset or set to 0. + if (NULL != nacl_enable_ppapi_dev) + enabled = strtol(nacl_enable_ppapi_dev, (char **) 0, 0); + if (enabled == 0) { + DebugPrintf("Skipping NaCl File test, NACL_ENABLE_PPAPI_DEV not set.\n"); + return; + } + const int kNumThreads = 8; + pthread_t thread[kNumThreads]; + ThreadInfo info; + unsigned int rseed = 123456; + info.threaded = false; + info.rseed = rand_r(&rseed); + // Run the test once from the main thread, as the only thread. + test_nacl_file_thread(&info); + info.threaded = true; + // The following test creates threads to test basic file I/O. + // This way we can also ensure that the abstraction is not broken if one + // tries to open/manipulate/close the same NaClFile more then once. + for (int i = 0; i < kNumThreads; ++i) { + info.rseed = rand_r(&rseed); + int p = pthread_create(&thread[i], NULL, test_nacl_file_thread, &info); + CHECK(0 == p); + } + // Run the test from the main thread again, this time competing with + // the other threads. + info.rseed = rand_r(&rseed); + test_nacl_file_thread(&info); + // Give the threads a chance to start racing before joining them. + usleep(100000); + for (int i = 0; i < kNumThreads; ++i) { + pthread_join(thread[i], NULL); + } +} diff --git a/ppapi/native_client/tests/ppapi_geturl/nacl_file_main.h b/ppapi/native_client/tests/ppapi_geturl/nacl_file_main.h new file mode 100644 index 0000000..326a6fe --- /dev/null +++ b/ppapi/native_client/tests/ppapi_geturl/nacl_file_main.h @@ -0,0 +1,10 @@ +// 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. + +#ifndef TESTS_PPAPI_GETURL_NACL_FILE_MAIN_H_ +#define TESTS_PPAPI_GETURL_NACL_FILE_MAIN_H_ + +extern void test_nacl_file(); + +#endif diff --git a/ppapi/native_client/tests/ppapi_geturl/ppapi_geturl.cc b/ppapi/native_client/tests/ppapi_geturl/ppapi_geturl.cc new file mode 100644 index 0000000..c6ad427 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_geturl/ppapi_geturl.cc @@ -0,0 +1,39 @@ +// Copyright 2010 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 <cstdio> +#include <cstdlib> + +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/ppb_instance.h" + +#include "native_client/tests/ppapi_geturl/module.h" + +// Global PPP functions -------------------------------------------------------- + +PP_EXPORT int32_t PPP_InitializeModule(PP_Module module_id, + PPB_GetInterface get_browser_interface) { + printf("--- PPP_InitializeModule\n"); + fflush(stdout); + + Module* module = Module::Create(module_id, get_browser_interface); + if (NULL == module) + return PP_ERROR_FAILED; + return PP_OK; +} + +PP_EXPORT void PPP_ShutdownModule() { + printf("--- PPP_ShutdownModule\n"); + fflush(stdout); + Module::Free(); +} + +PP_EXPORT const void* PPP_GetInterface(const char* interface_name) { + printf("--- PPP_GetInterface(%s)\n", interface_name); + fflush(stdout); + Module* module = Module::Get(); + if (NULL == module) + return NULL; + return module->GetPluginInterface(interface_name); +} diff --git a/ppapi/native_client/tests/ppapi_geturl/ppapi_geturl.html b/ppapi/native_client/tests/ppapi_geturl/ppapi_geturl.html new file mode 100644 index 0000000..db75192 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_geturl/ppapi_geturl.html @@ -0,0 +1,102 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + <!-- Copyright (c) 2011 Google Inc. All rights reserved. --> + <head> + <META HTTP-EQUIV="Pragma" CONTENT="no-cache" /> + <META HTTP-EQUIV="Expires" CONTENT="-1" /> + <script type="text/javascript" src="nacltest.js"></script> + <script type="text/javascript"> + //<![CDATA[ + // These constants need to match their corresponding values in module.cc. + var ARGUMENT_SEPARATOR = '|'; + var TRUE_STRING_VALUE = '1'; + var FALSE_STRING_VALUE = '0'; + + function isMatch(actual, expected) { + return (0 <= actual.indexOf(expected)); + } + + // Convert a string to a boolean value. '1' convertes to |true|, + // anything else converts to |false|. + function stringToBool(str_value) { + return str_value == TRUE_STRING_VALUE; + } + + // Convert a boolean value to the corresponding string value. |true| + // converts to '1', |false| to '0'. + function boolToString(bool_value) { + return bool_value ? TRUE_STRING_VALUE : FALSE_STRING_VALUE; + } + + function setupTests(tester, plugin) { + function addTest(name, url, as_file, expected_data, expected_success) { + tester.addAsyncTest(name, function(test) { + var listener = test.wrap(function(test_response) { + plugin.removeEventListener('message', listener, false); + + var response_args = + test_response.data.split(ARGUMENT_SEPARATOR); + test.assertEqual(response_args.length, 4); + + // Validate the results. + var response_url = response_args[0]; + var response_as_file = stringToBool(response_args[1]); + var response_data = response_args[2]; + var response_success = stringToBool(response_args[3]); + test.assert(isMatch(response_url, url)); + test.assertEqual(response_as_file, as_file); + test.log(response_data); + test.assert(isMatch(response_data, expected_data)); + test.assertEqual(response_success, expected_success); + test.pass(); + }); + plugin.addEventListener('message', listener, false); + + // Make the request. + var loadUrlMessage = [ + 'loadUrl', + url, + boolToString(as_file)].join(ARGUMENT_SEPARATOR); + plugin.postMessage(loadUrlMessage); + }); + } + + var VALID_URL = 'ppapi_geturl_success.html'; + var CROSSORIGIN_URL = 'http://www.google.com/robots.txt'; + var INVALID_URL = 'ppapi_nonexistent_url.html'; + + addTest('Valid', VALID_URL, false, 'TEST PASSED', true); + addTest('Valid_File', VALID_URL, true, 'TEST PASSED', true); + addTest('CrossOrigin', CROSSORIGIN_URL, false, 'PP_ERROR_NOACCESS', + false); + addTest('CrossOrigin_File', CROSSORIGIN_URL, true, 'PP_ERROR_NOACCESS', + false); + addTest('Invalid', INVALID_URL, false, '404', false); + addTest('Invalid_File', INVALID_URL, true, '404', false); + } + //]]> + </script> + + <title>PPAPI GetURL Test</title> + </head> + <body> + <h1>PPAPI GetURL Test</h1> + + <embed type="application/x-nacl" + id="nacl" + name="nacl_module" + src="ppapi_geturl.nmf" + width="0" height="0" /> + + <script type="text/javascript"> + //<![CDATA[ + // TODO(ncbray) allow the test to run in parallel + var tester = new Tester(); + setupTests(tester, $('nacl')); + tester.waitFor($('nacl')); + tester.run(); + //]]> + </script> + </body> +</html> diff --git a/ppapi/native_client/tests/ppapi_geturl/ppapi_geturl.nmf b/ppapi/native_client/tests/ppapi_geturl/ppapi_geturl.nmf new file mode 100644 index 0000000..948f8c7 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_geturl/ppapi_geturl.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_geturl_x86-32.nexe"}, + "x86-64": {"url": "ppapi_geturl_x86-64.nexe"}, + "arm": {"url": "ppapi_geturl_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_geturl/ppapi_geturl_success.html b/ppapi/native_client/tests/ppapi_geturl/ppapi_geturl_success.html new file mode 100644 index 0000000..0bda3ee --- /dev/null +++ b/ppapi/native_client/tests/ppapi_geturl/ppapi_geturl_success.html @@ -0,0 +1,5 @@ +TEST PASSED + The test code searches for the above string + in this file to ensure that the file was loaded. + If you are seeing the contents of this page as part of the test output, + then the test passed. diff --git a/ppapi/native_client/tests/ppapi_geturl/url_load_request.cc b/ppapi/native_client/tests/ppapi_geturl/url_load_request.cc new file mode 100644 index 0000000..0eb3502 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_geturl/url_load_request.cc @@ -0,0 +1,350 @@ +// 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/tests/ppapi_geturl/url_load_request.h" + +#include <stdio.h> +#include <string> +#include <sstream> + +#include "native_client/src/include/portability.h" +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/tests/ppapi_geturl/module.h" +#include "ppapi/c/pp_bool.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" + +namespace { + +// A local helper that does not contribute to loading/reading of urls, but +// allows us to test proxying of Is<Interface> functions. +// TODO(polina): when we have unit tests, move this there. +void TestIsInterface(std::string test_interface, + PP_Resource resource, + const PPB_FileIO* ppb_fileio, + const PPB_URLRequestInfo* ppb_url_request_info, + const PPB_URLResponseInfo* ppb_url_response_info, + const PPB_URLLoader* ppb_url_loader) { + printf("--- TestIsInterface: %s\n", test_interface.c_str()); + if (test_interface == PPB_FILEIO_INTERFACE) { + CHECK(ppb_fileio->IsFileIO(resource) == PP_TRUE); + CHECK(ppb_url_request_info->IsURLRequestInfo(resource) == PP_FALSE); + CHECK(ppb_url_response_info->IsURLResponseInfo(resource) == PP_FALSE); + CHECK(ppb_url_loader->IsURLLoader(resource) == PP_FALSE); + } else if (test_interface == PPB_URLREQUESTINFO_INTERFACE) { + CHECK(ppb_fileio->IsFileIO(resource) == PP_FALSE); + CHECK(ppb_url_request_info->IsURLRequestInfo(resource) == PP_TRUE); + CHECK(ppb_url_response_info->IsURLResponseInfo(resource) == PP_FALSE); + CHECK(ppb_url_loader->IsURLLoader(resource) == PP_FALSE); + } else if (test_interface == PPB_URLRESPONSEINFO_INTERFACE) { + CHECK(ppb_fileio->IsFileIO(resource) == PP_FALSE); + CHECK(ppb_url_request_info->IsURLRequestInfo(resource) == PP_FALSE); + CHECK(ppb_url_response_info->IsURLResponseInfo(resource) == PP_TRUE); + CHECK(ppb_url_loader->IsURLLoader(resource) == PP_FALSE); + } else if (test_interface == PPB_URLLOADER_INTERFACE) { + CHECK(ppb_fileio->IsFileIO(resource) == PP_FALSE); + CHECK(ppb_url_request_info->IsURLRequestInfo(resource) == PP_FALSE); + CHECK(ppb_url_response_info->IsURLResponseInfo(resource) == PP_FALSE); + CHECK(ppb_url_loader->IsURLLoader(resource) == PP_TRUE); + } +} + +void OpenCallback(void* user_data, int32_t pp_error) { + UrlLoadRequest* obj = reinterpret_cast<UrlLoadRequest*>(user_data); + if (NULL != obj) + obj->OpenCallback(pp_error); +} + +void FinishStreamingToFileCallback(void* user_data, int32_t pp_error) { + UrlLoadRequest* obj = reinterpret_cast<UrlLoadRequest*>(user_data); + if (NULL != obj) + obj->FinishStreamingToFileCallback(pp_error); +} + +void ReadResponseBodyCallback(void* user_data, int32_t pp_error_or_bytes) { + UrlLoadRequest* obj = reinterpret_cast<UrlLoadRequest*>(user_data); + if (NULL != obj) + obj->ReadResponseBodyCallback(pp_error_or_bytes); +} + +void OpenFileBodyCallback(void* user_data, int32_t pp_error) { + UrlLoadRequest* obj = reinterpret_cast<UrlLoadRequest*>(user_data); + if (NULL != obj) + obj->OpenFileBodyCallback(pp_error); +} + +void ReadFileBodyCallback(void* user_data, int32_t pp_error_or_bytes) { + UrlLoadRequest* obj = reinterpret_cast<UrlLoadRequest*>(user_data); + if (NULL != obj) + obj->ReadFileBodyCallback(pp_error_or_bytes); +} + +} // namespace + + +UrlLoadRequest::UrlLoadRequest(PP_Instance instance) + : delete_this_after_report(false), + as_file_(false), + instance_(instance), + request_(0), + loader_(0), + response_(0), + fileio_(0), + request_interface_(NULL), + loader_interface_(NULL), + fileio_interface_(NULL), + read_offset_(0) { +} + +UrlLoadRequest::~UrlLoadRequest() { + Clear(); +} + +void UrlLoadRequest::Clear() { + Module* module = Module::Get(); + if (0 != request_) { + module->ppb_core_interface()->ReleaseResource(request_); + request_ = 0; + } + if (0 != loader_) { + module->ppb_core_interface()->ReleaseResource(loader_); + loader_ = 0; + } + if (0 != response_) { + module->ppb_core_interface()->ReleaseResource(response_); + response_ = 0; + } + if (0 != fileio_) { + module->ppb_core_interface()->ReleaseResource(fileio_); + fileio_ = 0; + } + url_body_.clear(); +} + +bool UrlLoadRequest::ReportSuccess() { + Module::Get()->ReportResult( + instance_, url_.c_str(), as_file_, url_body_.c_str(), true); + if (delete_this_after_report) { + delete this; + } + return true; +} + +bool UrlLoadRequest::ReportFailure(const std::string& error) { + Module::Get()->ReportResult( + instance_, url_.c_str(), as_file_, error.c_str(), false); + if (delete_this_after_report) { + delete this; + } + return false; +} + +bool UrlLoadRequest::ReportFailure(const std::string& message, + int32_t pp_error) { + std::string error = message; + error.append(Module::ErrorCodeToStr(pp_error)); + return ReportFailure(error); +} + +bool UrlLoadRequest::Load(bool as_file, std::string url) { + printf("--- UrlLoadRequest::Load(as_file=%d, '%s')\n", as_file, url.c_str()); + url_ = url; + as_file_ = as_file; + Clear(); + std::string error; + if (!GetRequiredInterfaces(&error)) { + return ReportFailure(error); + } + PP_Bool set_url = request_interface_->SetProperty( + request_, PP_URLREQUESTPROPERTY_URL, Module::StrToVar(url)); + PP_Bool set_method = request_interface_->SetProperty( + request_, PP_URLREQUESTPROPERTY_METHOD, Module::StrToVar("GET")); + PP_Bool pp_as_file = as_file ? PP_TRUE : PP_FALSE; + PP_Bool set_file = request_interface_->SetProperty( + request_, PP_URLREQUESTPROPERTY_STREAMTOFILE, PP_MakeBool(pp_as_file)); + if (set_url != PP_TRUE || set_method != PP_TRUE || set_file != PP_TRUE) { + return ReportFailure("PPB_URLRequestInfo::SetProperty: failed"); + } + loader_interface_->Open( + loader_, + request_, + PP_MakeCompletionCallback(::OpenCallback, this)); + return true; +} + +bool UrlLoadRequest::GetRequiredInterfaces(std::string* error) { + Module* module = Module::Get(); + + request_interface_ = static_cast<const PPB_URLRequestInfo*>( + module->GetBrowserInterface(PPB_URLREQUESTINFO_INTERFACE)); + if (NULL == request_interface_) { + *error = "Failed to get browser interface '" PPB_URLREQUESTINFO_INTERFACE; + return false; + } + request_ = request_interface_->Create(instance_); + if (0 == request_) { + *error = "PPB_URLRequestInfo::Create: failed"; + return false; + } + + response_interface_ = static_cast<const PPB_URLResponseInfo*>( + module->GetBrowserInterface(PPB_URLRESPONSEINFO_INTERFACE)); + if (NULL == response_interface_) { + *error = "Failed to get browser interface '" PPB_URLRESPONSEINFO_INTERFACE; + return false; + } + + loader_interface_ = static_cast<const PPB_URLLoader*>( + module->GetBrowserInterface(PPB_URLLOADER_INTERFACE)); + if (NULL == loader_interface_) { + *error = "Failed to get browser interface '" PPB_URLLOADER_INTERFACE; + return false; + } + loader_ = loader_interface_->Create(instance_); + if (0 == loader_) { + *error = "PPB_URLLoader::Create: failed"; + return false; + } + + fileio_interface_ = static_cast<const PPB_FileIO*>( + module->GetBrowserInterface(PPB_FILEIO_INTERFACE)); + if (NULL == fileio_interface_) { + *error = "Failed to get browser interface '" PPB_FILEIO_INTERFACE; + return false; + } + fileio_ = fileio_interface_->Create(instance_); + if (0 == fileio_) { + *error = "PPB_FileIO::Create: failed"; + return false; + } + + TestIsInterface(PPB_URLREQUESTINFO_INTERFACE, request_, + fileio_interface_, request_interface_, response_interface_, + loader_interface_); + TestIsInterface(PPB_URLLOADER_INTERFACE, loader_, + fileio_interface_, request_interface_, response_interface_, + loader_interface_); + TestIsInterface(PPB_FILEIO_INTERFACE, fileio_, + fileio_interface_, request_interface_, response_interface_, + loader_interface_); + + return true; +} + +void UrlLoadRequest::ReadResponseBody() { + loader_interface_->ReadResponseBody( + loader_, + buffer_, + sizeof(buffer_), + PP_MakeCompletionCallback(::ReadResponseBodyCallback, this)); +} + +void UrlLoadRequest::ReadFileBody() { + fileio_interface_->Read( + fileio_, + read_offset_, + buffer_, + sizeof(buffer_), + PP_MakeCompletionCallback(::ReadFileBodyCallback, this)); +} + +void UrlLoadRequest::OpenCallback(int32_t pp_error) { + printf("--- UrlLoadRequest::OpenCallback\n"); + if (pp_error != PP_OK) { + ReportFailure("UrlLoadRequest::OpenCallback: ", pp_error); + return; + } + + // Validating response headers to confirm successful loading. + response_ = loader_interface_->GetResponseInfo(loader_); + if (0 == response_) { + ReportFailure("UrlLoadRequest::OpenCallback: null response"); + return; + } + TestIsInterface(PPB_URLRESPONSEINFO_INTERFACE, response_, + fileio_interface_, request_interface_, response_interface_, + loader_interface_); + PP_Var url = response_interface_->GetProperty(response_, + PP_URLRESPONSEPROPERTY_URL); + if (url.type != PP_VARTYPE_STRING) { + ReportFailure("URLLoadRequest::OpenCallback: bad url type"); + return; + } + url_ = Module::VarToStr(url); // Update url to be fully qualified. + PP_Var status_code = + response_interface_->GetProperty(response_, + PP_URLRESPONSEPROPERTY_STATUSCODE); + int32_t status_code_as_int = status_code.value.as_int; + if (status_code_as_int != 200) { // Not HTTP OK. + std::stringstream error; + error << "OpenCallback: status_code=" << status_code_as_int; + ReportFailure(error.str()); + return; + } + + if (as_file_) { + loader_interface_->FinishStreamingToFile( + loader_, + PP_MakeCompletionCallback(::FinishStreamingToFileCallback, this)); + } else { + ReadResponseBody(); + } +} + +void UrlLoadRequest::FinishStreamingToFileCallback(int32_t pp_error) { + printf("--- UrlLoadRequest::FinishStreamingToFileCallback\n"); + if (pp_error != PP_OK) { + ReportFailure("UrlLoadRequest::FinishStreamingToFileCallback: ", pp_error); + return; + } + PP_Resource fileref = response_interface_->GetBodyAsFileRef(response_); + if (0 == fileref) { + ReportFailure("UrlLoadRequest::FinishStreamingToFileCallback: null file"); + return; + } + fileio_interface_->Open( + fileio_, + fileref, + PP_FILEOPENFLAG_READ, + PP_MakeCompletionCallback(::OpenFileBodyCallback, this)); +} + +void UrlLoadRequest::ReadResponseBodyCallback(int32_t pp_error_or_bytes) { + printf("--- UrlLoadRequest::ReadResponseBodyCallback\n"); + if (pp_error_or_bytes < PP_OK) { + ReportFailure("UrlLoadRequest::ReadResponseBodyCallback: ", + pp_error_or_bytes); + } else if (pp_error_or_bytes == PP_OK) { // Reached EOF. + ReportSuccess(); + } else { // Partial read, so copy out the buffer and continue reading. + for (int32_t i = 0; i < pp_error_or_bytes; i++) + url_body_.push_back(buffer_[i]); + ReadResponseBody(); + } +} + +void UrlLoadRequest::ReadFileBodyCallback(int32_t pp_error_or_bytes) { + printf("--- UrlLoadRequest::ReadFileBodyCallback\n"); + if (pp_error_or_bytes < PP_OK) { + ReportFailure("UrlLoadRequest::ReadFileBodyCallback: ", + pp_error_or_bytes); + } else if (pp_error_or_bytes == PP_OK) { // Reached EOF. + ReportSuccess(); + } else { // Partial read, so copy out the buffer and continue reading. + for (int32_t i = 0; i < pp_error_or_bytes; i++) + url_body_.push_back(buffer_[i]); + read_offset_ += pp_error_or_bytes; + ReadFileBody(); + } +} + +void UrlLoadRequest::OpenFileBodyCallback(int32_t pp_error) { + printf("--- UrlLoadRequest::OpenFileBodyCallback\n"); + if (pp_error != PP_OK) { + ReportFailure("UrlLoadRequest::OpenFileBodyCallback: ", pp_error); + return; + } + ReadFileBody(); +} diff --git a/ppapi/native_client/tests/ppapi_geturl/url_load_request.h b/ppapi/native_client/tests/ppapi_geturl/url_load_request.h new file mode 100644 index 0000000..7ff98d5 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_geturl/url_load_request.h @@ -0,0 +1,79 @@ +// 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. +#ifndef TESTS_PPAPI_GETURL_URL_LOAD_REQUEST_H_ +#define TESTS_PPAPI_GETURL_URL_LOAD_REQUEST_H_ + +#include <string> +#include <vector> + +#include "ppapi/c/ppb_file_io.h" +#include "ppapi/c/ppb_file_ref.h" +#include "ppapi/c/ppb_url_loader.h" +#include "ppapi/c/ppb_url_request_info.h" +#include "ppapi/c/ppb_url_response_info.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/pp_stdint.h" +#if __native_client__ +// TODO(polina): add file_io_nacl include +#else +#include "ppapi/c/trusted/ppb_file_io_trusted.h" +#endif + + +class UrlLoadRequest { + public: + explicit UrlLoadRequest(PP_Instance instance); + ~UrlLoadRequest(); + bool Load(bool stream_as_file, std::string url); + + void OpenCallback(int32_t pp_error); + // Loading/reading via response includes the following asynchronous steps: + // 1) URLLoader::Open + // 2) URLLoader::ReadResponseBody (in a loop until EOF) + void ReadResponseBodyCallback(int32_t pp_error_or_bytes); + // Loading/reading via file includes the following asynchronous steps: + // 1) URLLoader::Open + // 2) URLLoader::FinishStreamingToFile + // 3) FileIO::Open + // 4) FileIO::Read (in a loop until EOF) + void FinishStreamingToFileCallback(int32_t pp_error); + void OpenFileBodyCallback(int32_t pp_error); + void ReadFileBodyCallback(int32_t pp_error_or_bytes); + + void set_delete_this_after_report() { delete_this_after_report = true; } + + private: + bool GetRequiredInterfaces(std::string* error); + void Clear(); + + void ReadResponseBody(); + void ReadFileBody(); + + bool ReportSuccess(); + bool ReportFailure(const std::string& error); + bool ReportFailure(const std::string& message, int32_t pp_error); + + bool delete_this_after_report; + + std::string url_; + bool as_file_; + + PP_Instance instance_; + PP_Resource request_; + PP_Resource loader_; + PP_Resource response_; + PP_Resource fileio_; + + const PPB_URLRequestInfo* request_interface_; + const PPB_URLResponseInfo* response_interface_; + const PPB_URLLoader* loader_interface_; + const PPB_FileIO* fileio_interface_; + + char buffer_[1024]; + std::string url_body_; + int32_t read_offset_; +}; + +#endif // TESTS_PPAPI_GETURL_URL_LOAD_REQUEST_H_ diff --git a/ppapi/native_client/tests/ppapi_gles_book/nacl.scons b/ppapi/native_client/tests/ppapi_gles_book/nacl.scons new file mode 100644 index 0000000..0205887 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_gles_book/nacl.scons @@ -0,0 +1,85 @@ +# -*- python -*- +# Copyright 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. + +# OpenGL ES examples + +Import('env') + +env.Prepend(CPPDEFINES=['XP_UNIX']) + +# Underlay $SOURCE_ROOT/gpu in this directory. +Dir('.').addRepository(Dir('#/../gpu')) + +# Underlay $SOURCE_ROOT/third_party/gles2_book in this directory. +Dir('.').addRepository(Dir('#/../third_party/gles2_book')) + +# Don't warn on pointer signedness issues (third_party sources) +env.Append(CFLAGS=['-Wno-pointer-sign']) +# ..and don't warn about missing braces +env.Append(CCFLAGS=['-Wno-missing-braces']) + +# Add local path to find GPU sources and GLES2 includes. +env.Append(CPPPATH=[ + '$SOURCE_ROOT/third_party/gles2_book/Common/Include', + '$SOURCE_ROOT/ppapi/lib/gl/include', + ]) + +gles_demo_srcs = [ + 'Common/Source/esShader.c', + 'Common/Source/esShapes.c', + 'Common/Source/esTransform.c', + 'Common/Source/esUtil.c', + 'demos/framework/demo.cc', + 'demos/framework/pepper.cc', + ] + +env.ComponentLibrary('ppapi_gles_demo', gles_demo_srcs) + +gles_book_examples = { + 'hello_triangle': [ + 'Chapter_2/Hello_Triangle/Hello_Triangle.c'], + 'mip_map_2d': [ + 'Chapter_9/MipMap2D/MipMap2D.c'], + 'simple_texture_2d': [ + 'Chapter_9/Simple_Texture2D/Simple_Texture2D.c'], + 'simple_texture_cubemap': [ + 'Chapter_9/Simple_TextureCubemap/Simple_TextureCubemap.c'], + 'simple_vertex_shader': [ + 'Chapter_8/Simple_VertexShader/Simple_VertexShader.c'], + 'stencil_test': [ + 'Chapter_11/Stencil_Test/Stencil_Test.c'], + 'texture_wrap': [ + 'Chapter_9/TextureWrap/TextureWrap.c'], +} + +for demo, sources in gles_book_examples.iteritems(): + nexe_name = ('ppapi_gles_book_%s_%s' + % (demo, env.get('TARGET_FULLARCH'))) + nmf_name = 'ppapi_gles_book_' + demo + '.nmf' + nexe = env.ComponentProgram( + nexe_name, + ['demos/gles2_book/demo_' + demo + '.cc'] + sources, + EXTRA_LIBS=['${PPAPI_LIBS}', + 'ppapi_cpp', + 'ppapi_gles_demo', + 'ppapi_cpp', + 'ppapi_gles2', + 'm']) + env.Publish(nexe_name, 'run', + ['ppapi_gles_book.html', + nmf_name]) + test = env.PPAPIBrowserTester( + 'ppapi_gles_book_' + demo + '.out', + url='ppapi_gles_book.html?manifest=' + nmf_name, + files=[nexe, + env.File(nmf_name), + env.File('ppapi_gles_book.html')], + browser_flags=['--enable-accelerated-plugins']) + env.AddNodeToTestSuite( + test, + ['chrome_browser_tests'], + 'run_ppapi_gles_book_' + demo + '_test', + is_broken=env.PPAPIBrowserTesterIsBroken() or + env.PPAPIGraphics3DIsBroken()) diff --git a/ppapi/native_client/tests/ppapi_gles_book/ppapi_gles_book.html b/ppapi/native_client/tests/ppapi_gles_book/ppapi_gles_book.html new file mode 100644 index 0000000..40640d1 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_gles_book/ppapi_gles_book.html @@ -0,0 +1,101 @@ +<!-- + Copyright 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. +--> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> + <head> + <meta http-equiv="Pragma" content="no-cache" /> + <meta http-equiv="Expires" content="-1" /> + <script type="text/javascript" src="nacltest.js"></script> + <title>PPAPI OpenGL ES Book Examples</title> + </head> + + <body> + <h1>PPAPI OpenGL ES Book Examples</h1> + <table style="border-spacing: 20pt;" summary="List of GLES book tests"> + <tr style="vertical-align: top;"> + <td> + <h2>Examples available and expected output</h2> + <p><a href="?manifest=ppapi_gles_book_hello_triangle.nmf"> + hello_triangle</a> + Red triangle</p> + <p><a href="?manifest=ppapi_gles_book_mip_map_2d.nmf">mip_map_2d</a> + Two red/blue chess board-patterned planes</p> + <p><a href="?manifest=ppapi_gles_book_simple_texture_2d.nmf"> + simple_texture_2d</a> + 2x2 matrix with red, green, blue, and yellow squares</p> + <p><a href="?manifest=ppapi_gles_book_simple_texture_cubemap.nmf"> + simple_texture_cubemap</a> + Ball with blue, red, yellow, and green patches; purple in the + center.</p> + <p><a href="?manifest=ppapi_gles_book_simple_vertex_shader.nmf"> + simple_vertex_shader</a> + Rotating red square</p> + <p><a href="?manifest=ppapi_gles_book_stencil_test.nmf">stencil_test</a> + EXPECTED OUTPUT UNKNOWN</p> + <p><a href="?manifest=ppapi_gles_book_texture_wrap.nmf">texture_wrap</a> + Three blue/red patterns</p> + <h2>Troubleshooting</h2> + <p>Make sure you start Chrome with + <tt>--enable-accelerated-plugins</tt>.</p> + <p>Check the JavaScript console.</p> + </td> + <td> + <div id="attach" style="background-image: + url(http://www.google.com/intl/en_ALL/images/logo.gif); + background-repeat:repeat"></div> + </td> + </tr> + </table> + + <script type="text/javascript"> + //<![CDATA[ +function ExtractSearchParameter(name) { + var nameIndex = location.search.indexOf(name + '='); + if (nameIndex != -1) { + var value = location.search.substring(nameIndex + name.length + 1); + var endIndex = value.indexOf('&'); + if (endIndex != -1) + value = value.substring(0, endIndex); + return value; + } + return ''; +} + +function setupTests(tester, plugin) { + // This template is built for tests where we only need to (or can) + // verify that the nexe loaded successfully. We do this by inserting + // following dummy test. + // This only tests that loading and any start-up testing (typically + // within DidChangeView) returned success; there is no + // automated way of checking that it did as intended beyond that. + tester.addAsyncTest('DummyTestToEnsureLoadingComplete_' + manifest, + function(status) { status.pass(); }); +} + +var manifest = ExtractSearchParameter('manifest'); +if (!manifest) manifest = 'ppapi_gles_book_hello_triangle.nmf'; +document.title = 'Test ' + manifest; + +var node = document.createElement('div'); +node.innerHTML = '<embed id="naclModule" ' + + 'name="naclModule" ' + + 'width=400 height=400 ' + + 'src="' + manifest + '" ' + + 'basic_tests="1" ' + + 'stress_tests="0" ' + + 'type="application/x-nacl" ' + + ' />'; +document.getElementById('attach').appendChild(node); + +var tester = new Tester(); +setupTests(tester, $('naclModule')); +tester.waitFor($('naclModule')); +tester.run(); + //]]> + </script> + </body> +</html> diff --git a/ppapi/native_client/tests/ppapi_gles_book/ppapi_gles_book_hello_triangle.nmf b/ppapi/native_client/tests/ppapi_gles_book/ppapi_gles_book_hello_triangle.nmf new file mode 100644 index 0000000..694d416 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_gles_book/ppapi_gles_book_hello_triangle.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_gles_book_hello_triangle_x86-32.nexe"}, + "x86-64": {"url": "ppapi_gles_book_hello_triangle_x86-64.nexe"}, + "arm": {"url": "ppapi_gles_book_hello_triangle_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_gles_book/ppapi_gles_book_mip_map_2d.nmf b/ppapi/native_client/tests/ppapi_gles_book/ppapi_gles_book_mip_map_2d.nmf new file mode 100644 index 0000000..c0e1357 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_gles_book/ppapi_gles_book_mip_map_2d.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_gles_book_mip_map_2d_x86-32.nexe"}, + "x86-64": {"url": "ppapi_gles_book_mip_map_2d_x86-64.nexe"}, + "arm": {"url": "ppapi_gles_book_mip_map_2d_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_gles_book/ppapi_gles_book_simple_texture_2d.nmf b/ppapi/native_client/tests/ppapi_gles_book/ppapi_gles_book_simple_texture_2d.nmf new file mode 100644 index 0000000..3f47f1b --- /dev/null +++ b/ppapi/native_client/tests/ppapi_gles_book/ppapi_gles_book_simple_texture_2d.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_gles_book_simple_texture_2d_x86-32.nexe"}, + "x86-64": {"url": "ppapi_gles_book_simple_texture_2d_x86-64.nexe"}, + "arm": {"url": "ppapi_gles_book_simple_texture_2d_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_gles_book/ppapi_gles_book_simple_texture_cubemap.nmf b/ppapi/native_client/tests/ppapi_gles_book/ppapi_gles_book_simple_texture_cubemap.nmf new file mode 100644 index 0000000..230ea191 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_gles_book/ppapi_gles_book_simple_texture_cubemap.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_gles_book_simple_texture_cubemap_x86-32.nexe"}, + "x86-64": {"url": "ppapi_gles_book_simple_texture_cubemap_x86-64.nexe"}, + "arm": {"url": "ppapi_gles_book_simple_texture_cubemap_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_gles_book/ppapi_gles_book_simple_vertex_shader.nmf b/ppapi/native_client/tests/ppapi_gles_book/ppapi_gles_book_simple_vertex_shader.nmf new file mode 100644 index 0000000..12949c7 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_gles_book/ppapi_gles_book_simple_vertex_shader.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_gles_book_simple_vertex_shader_x86-32.nexe"}, + "x86-64": {"url": "ppapi_gles_book_simple_vertex_shader_x86-64.nexe"}, + "arm": {"url": "ppapi_gles_book_simple_vertex_shader_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_gles_book/ppapi_gles_book_stencil_test.nmf b/ppapi/native_client/tests/ppapi_gles_book/ppapi_gles_book_stencil_test.nmf new file mode 100644 index 0000000..260da7e --- /dev/null +++ b/ppapi/native_client/tests/ppapi_gles_book/ppapi_gles_book_stencil_test.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_gles_book_stencil_test_x86-32.nexe"}, + "x86-64": {"url": "ppapi_gles_book_stencil_test_x86-64.nexe"}, + "arm": {"url": "ppapi_gles_book_stencil_test_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_gles_book/ppapi_gles_book_texture_wrap.nmf b/ppapi/native_client/tests/ppapi_gles_book/ppapi_gles_book_texture_wrap.nmf new file mode 100644 index 0000000..d3f3eb7 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_gles_book/ppapi_gles_book_texture_wrap.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_gles_book_texture_wrap_x86-32.nexe"}, + "x86-64": {"url": "ppapi_gles_book_texture_wrap_x86-64.nexe"}, + "arm": {"url": "ppapi_gles_book_texture_wrap_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_messaging/Info.plist b/ppapi/native_client/tests/ppapi_messaging/Info.plist new file mode 100644 index 0000000..bf244bc --- /dev/null +++ b/ppapi/native_client/tests/ppapi_messaging/Info.plist @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>English</string> + <key>CFBundleExecutable</key> + <string>ppapi_messaging</string> + <key>CFBundleIdentifier</key> + <string>com.google.ppapi_messaging</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundlePackageType</key> + <string>BRPL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>nacl</string> + <key>CFBundleVersion</key> + <string>0.1</string> + <key>CFPlugInDynamicRegisterFunction</key> + <string></string> + <key>CFPlugInDynamicRegistration</key> + <string>NO</string> + <key>CFPlugInUnloadFunction</key> + <string></string> + <key>WebPluginDescription</key> + <string>ppapi_messaging</string> + <key>NSPrincipalClass</key> + <string>ppapi_messaging</string> + <key>WebPluginMIMETypes</key> + <dict> + <key>application/x-nacl</key> + <dict> + <key>WebPluginTypeDescription</key> + <string>PPAPI Native Client Graphics2D interaction</string> + <key>WebPluginExtensions</key> + <array> + <string>nexe,nacl</string> + </array> + </dict> + </dict> + <key>WebPluginName</key> + <string>ppapi_messaging</string> +</dict> +</plist> diff --git a/ppapi/native_client/tests/ppapi_messaging/build.scons b/ppapi/native_client/tests/ppapi_messaging/build.scons new file mode 100644 index 0000000..6a47a49 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_messaging/build.scons @@ -0,0 +1,60 @@ +# -*- python -*- +# Copyright 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. + +# A way to build the nexe as a trusted plugin to validate directly +# against Chrome on Linux and OS X using +# --register-pepper-plugins="/path/to/libppapi_messaging.so;application/x-nacl" +# http://localhost:5103/scons-out/nacl-x86-../staging/ppapi_messaging.html +# Note that a trusted plugin is not built on Windows. + +Import('env') + +plugin_env = env.Clone() + +sources = ['ppapi_messaging.c'] + +libs = ['imc', + 'gio', + 'pthread', + 'platform' + ] + +trusted_plugin = None +if plugin_env.Bit('linux'): # linux, arm + trusted_plugin = plugin_env.DualLibrary('ppapi_messaging', + sources) +elif plugin_env.Bit('mac'): # os x + plugin_env.Append( + FRAMEWORKS = ['Cocoa'], + LINKFLAGS = ['-bundle', '-framework', 'Foundation'] + ) + plugin_env['tools'] = 'target_platform_mac' + REZ = '/Developer/Tools/Rez' + plugin_env.Command(target='ppapi_messaging.rsrc', + source='ppapi_messaging.r', + action=[Action(REZ + ' -o ${TARGET} ${SOURCE} -useDF')]) + ppapi_messaging = plugin_env.ComponentProgram('ppapi_messaging', + sources, + EXTRA_LIBS=libs, + no_import_lib=True) + bundle_name = '${STAGING_DIR}/ppapi_messaging.bundle' + plugin_env.Alias('ppapi_messaging.bundle', [bundle_name]) + plugin_env.Bundle(bundle_name, + BUNDLE_EXE=ppapi_messaging, + BUNDLE_PKGINFO_FILENAME=0, + BUNDLE_RESOURCES='ppapi_messaging.rsrc', + BUNDLE_INFO_PLIST='Info.plist') + trusted_plugin = bundle_name + +if not trusted_plugin == None: + # Note that the html is required to run this program. + nacltest_js = '${SCONSTRUCT_DIR}/tools/browser_tester/browserdata/nacltest.js' + dest_copy = plugin_env.Replicate('$STAGING_DIR', + ['ppapi_messaging.html', + 'ppapi_messaging.nmf', + env.File(nacltest_js)] + ) + plugin_env.Depends(trusted_plugin, dest_copy) + diff --git a/ppapi/native_client/tests/ppapi_messaging/nacl.scons b/ppapi/native_client/tests/ppapi_messaging/nacl.scons new file mode 100644 index 0000000..4483570 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_messaging/nacl.scons @@ -0,0 +1,49 @@ +# -*- python -*- +# Copyright 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. + +# This is a C PPAPI +# +# ppapi_messaging.html - test driver that loads the nexe and scripts it +# ppapi_messaging.nmf - manifest file for serving platform specific nexe binary. +# +# ppapi_messaging.c - implementation of PPP interface and PPP_Instance + +Import('env') + +env.Prepend(CPPDEFINES=['XP_UNIX']) + +nexe = 'ppapi_messaging_%s' % env.get('TARGET_FULLARCH') + +env.Alias('ppapi_messaging${PROGSUFFIX}', + ['$STAGING_DIR/%s${PROGSUFFIX}' % nexe]) + +ppapi_messaging_nexe = env.ComponentProgram(nexe, + ['ppapi_messaging.c'], + EXTRA_LIBS=['${PPAPI_LIBS}', + 'platform', + 'gio', + 'pthread', + 'm', + ]) + +# Note that the html is required to run this program. +dest_copy = env.Replicate('$STAGING_DIR', + ['ppapi_messaging.html', + 'ppapi_messaging.nmf', + env.File('${SCONSTRUCT_DIR}/tools/browser_tester/' + 'browserdata/nacltest.js')] + ) +env.Depends(nexe, dest_copy) + +node = env.PPAPIBrowserTester('ppapi_messaging_browser_test.out', + url='ppapi_messaging.html', + files=[ppapi_messaging_nexe, + env.File('ppapi_messaging.nmf'), + env.File('ppapi_messaging.html')]) + +env.AddNodeToTestSuite(node, + ['chrome_browser_tests'], + 'run_ppapi_messaging_browser_test', + is_broken=env.PPAPIBrowserTesterIsBroken()) diff --git a/ppapi/native_client/tests/ppapi_messaging/ppapi_messaging.c b/ppapi/native_client/tests/ppapi_messaging/ppapi_messaging.c new file mode 100644 index 0000000..b2ee787 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_messaging/ppapi_messaging.c @@ -0,0 +1,152 @@ +/* + * 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 <stdio.h> +#include <string.h> + +#include "native_client/src/include/portability.h" +#include "native_client/src/shared/platform/nacl_check.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_var.h" +#include "ppapi/c/ppb.h" +#include "ppapi/c/ppb_core.h" +#include "ppapi/c/ppb_instance.h" +#include "ppapi/c/ppb_messaging.h" +#include "ppapi/c/ppb_var.h" +#include "ppapi/c/ppp.h" +#include "ppapi/c/ppp_instance.h" +#include "ppapi/c/ppp_messaging.h" + +/* Global variables */ +PPB_GetInterface get_browser_interface_func = NULL; +PP_Instance instance = 0; +PP_Module module = 0; + +struct MessageInfo { + PP_Instance instance; + struct PP_Var message; +}; + +static struct PPB_Var* GetPPB_Var() { + return (struct PPB_Var*)(*get_browser_interface_func)(PPB_VAR_INTERFACE); +} + +static void SendOnMessageEventCallback(void* data, int32_t result) { + struct MessageInfo* message_to_send = (struct MessageInfo*)data; + struct PPB_Messaging* ppb_messaging = + (struct PPB_Messaging*)(*get_browser_interface_func)( + PPB_MESSAGING_INTERFACE); + + UNREFERENCED_PARAMETER(result); + CHECK(ppb_messaging); + + ppb_messaging->PostMessage(message_to_send->instance, + message_to_send->message); + + /* Since the message we're sending originally was sent from the browser, + * and subequently copied, if sending a string message we need to + * dereference it. + */ + if (message_to_send->message.type == PP_VARTYPE_STRING) { + struct PPB_Var* ppb_var = GetPPB_Var(); + ppb_var->Release(message_to_send->message); + } + free(message_to_send); +} + +/* TODO(dspringer): We need to add a test that calls PostMessage directly from + * HandleMessage to ensure that this is all asynchronous. + */ +void HandleMessage(PP_Instance instance, struct PP_Var message) { + struct PPB_Core* ppb_core = + (struct PPB_Core*)(*get_browser_interface_func)(PPB_CORE_INTERFACE); + struct MessageInfo* message_to_send = malloc(sizeof(struct MessageInfo)); + message_to_send->instance = instance; + message_to_send->message = message; + + if (message.type == PP_VARTYPE_STRING) { + struct PPB_Var* ppb_var = GetPPB_Var(); + /* If the message is a string, add reference to go with the copy we did + * above. + */ + ppb_var->AddRef(message); + } + /* Echo message back to browser */ + ppb_core->CallOnMainThread( + 0, /* I don't care about delay */ + PP_MakeCompletionCallback(SendOnMessageEventCallback, message_to_send), + PP_OK); /* Dummy value for result */ +} + +PP_Bool DidCreate(PP_Instance instance, + uint32_t argc, + const char** argn, + const char** argv) { + UNREFERENCED_PARAMETER(instance); + UNREFERENCED_PARAMETER(argc); + UNREFERENCED_PARAMETER(argn); + UNREFERENCED_PARAMETER(argv); + return PP_TRUE; +} + +void DidDestroy(PP_Instance instance) { + UNREFERENCED_PARAMETER(instance); +} + +void DidChangeView(PP_Instance instance, + const struct PP_Rect* position, + const struct PP_Rect* clip) { + UNREFERENCED_PARAMETER(instance); + UNREFERENCED_PARAMETER(position); + UNREFERENCED_PARAMETER(clip); +} + +void DidChangeFocus(PP_Instance instance, + PP_Bool has_focus) { + UNREFERENCED_PARAMETER(instance); + UNREFERENCED_PARAMETER(has_focus); +} + +static PP_Bool HandleDocumentLoad(PP_Instance instance, + PP_Resource url_loader) { + UNREFERENCED_PARAMETER(instance); + UNREFERENCED_PARAMETER(url_loader); + return PP_TRUE; +} + +/* Implementations of the PPP entry points expected by the browser. */ +PP_EXPORT int32_t PPP_InitializeModule(PP_Module module_id, + PPB_GetInterface get_browser_interface) { + module = module_id; + get_browser_interface_func = get_browser_interface; + return PP_OK; +} + +PP_EXPORT void PPP_ShutdownModule() { +} + +PP_EXPORT const void* PPP_GetInterface(const char* interface_name) { + if (0 == strncmp(PPP_INSTANCE_INTERFACE, interface_name, + strlen(PPP_INSTANCE_INTERFACE))) { + static struct PPP_Instance instance_interface = { + DidCreate, + DidDestroy, + DidChangeView, + DidChangeFocus, + HandleDocumentLoad + }; + return &instance_interface; + } else if (0 == strncmp(PPP_MESSAGING_INTERFACE, interface_name, + strlen(PPP_MESSAGING_INTERFACE))) { + static struct PPP_Messaging messaging_interface = { + HandleMessage + }; + return &messaging_interface; + } + return NULL; +} diff --git a/ppapi/native_client/tests/ppapi_messaging/ppapi_messaging.html b/ppapi/native_client/tests/ppapi_messaging/ppapi_messaging.html new file mode 100644 index 0000000..4183111 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_messaging/ppapi_messaging.html @@ -0,0 +1,64 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + <!-- Copyright 2011 Google Inc. All rights reserved. --> + <head> + <META HTTP-EQUIV="Pragma" CONTENT="no-cache" /> + <META HTTP-EQUIV="Expires" CONTENT="-1" /> + <script type="text/javascript" src="nacltest.js"></script> + <script type="application/x-javascript"> + //<![CDATA[ + function setupTests(tester, plugin) { + function TestPostMessageAndOnMessage(status, messageToSend) { + var listener = status.wrap(function(message) { + plugin.removeEventListener("message", listener, false); + status.log('Received onmessage event: ' + message.data); + // Verify the message received against the message sent. + status.assertEqual(message.data, messageToSend); + status.assertEqual(typeof(message.data), typeof(messageToSend)); + status.pass(); + }); + + plugin.addEventListener("message", listener, false); + plugin.postMessage(messageToSend); + } + + tester.addAsyncTest('PPB/PPP_Messaging:String', function(status) { + TestPostMessageAndOnMessage(status, 'Some String Value'); + }); + tester.addAsyncTest('PPB/PPP_Messaging:Double', function(status) { + TestPostMessageAndOnMessage(status, 3.14); // dummy double value + }); + tester.addAsyncTest('PPB/PPP_Messaging:Int', function(status) { + TestPostMessageAndOnMessage(status, 8); // dummy integer value + }); + tester.addAsyncTest('PPB/PPP_Messaging:Null', function(status) { + TestPostMessageAndOnMessage(status, null); + }); + tester.addAsyncTest('PPB/PPP_Messaging:Undefined', function(status) { + TestPostMessageAndOnMessage(status, undefined); + }); + // TODO(dspringer): Add tests for other types like object, array, etc. + } + //]]> + </script> + <title>PPAPI PPB_Messaging Test</title> + </head> + <body> + <h1>PPAPI PPB_Messaging Test</h1> + + <embed type="application/x-nacl" id="test_nexe" + name="nacl_module" + src="ppapi_messaging.nmf" + width="0" height="0" /> + + <script type="text/javascript"> + //<![CDATA[ + var tester = new Tester(); + setupTests(tester, $('test_nexe')); + tester.waitFor($('test_nexe')); + tester.run(); + //]]> + </script> + </body> +</html> diff --git a/ppapi/native_client/tests/ppapi_messaging/ppapi_messaging.nmf b/ppapi/native_client/tests/ppapi_messaging/ppapi_messaging.nmf new file mode 100644 index 0000000..6210896 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_messaging/ppapi_messaging.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-64": {"url": "ppapi_messaging_x86-64.nexe"}, + "x86-32": {"url": "ppapi_messaging_x86-32.nexe"}, + "arm": {"url": "ppapi_messaging_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_messaging/ppapi_messaging.r b/ppapi/native_client/tests/ppapi_messaging/ppapi_messaging.r new file mode 100644 index 0000000..af3f807 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_messaging/ppapi_messaging.r @@ -0,0 +1,15 @@ +#include <CoreServices/CoreServices.r> + +resource 'STR#' (126) { { + "PPAPI NativeClient", + "PPAPI NativeClient Plug-in" +} }; + +resource 'STR#' (127) { { + "PPAPI NativeClient Module - SRPC", +} }; + +resource 'STR#' (128) { { + "application/x-nacl", + "nexe", +} }; diff --git a/ppapi/native_client/tests/ppapi_simple_tests/audio.cc b/ppapi/native_client/tests/ppapi_simple_tests/audio.cc new file mode 100644 index 0000000..4b3d8a0 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_simple_tests/audio.cc @@ -0,0 +1,154 @@ +// 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 <stdint.h> + +#include <cmath> +#include <limits> +#include <string> + +#include <nacl/nacl_check.h> +#include <nacl/nacl_log.h> + +#include "ppapi/c/pp_bool.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/ppb_audio.h" +#include "ppapi/c/ppb_audio_config.h" +#include "ppapi/cpp/audio.h" +#include "ppapi/cpp/audio_config.h" +#include "ppapi/cpp/completion_callback.h" +#include "ppapi/cpp/instance.h" +#include "ppapi/cpp/module.h" + +const PP_AudioSampleRate kSampleFrequency = PP_AUDIOSAMPLERATE_44100; +// Buffer size in units of sample frames. +// 4096 is a conservative size that should avoid underruns on most systems. +const uint32_t kSampleFrameCount = 4096; +const uint32_t kDefaultFrequency = 400; +const uint32_t kDefaultDuration = 10000; + +const int kNumChannelsForStereo = 2; +const size_t kSizeSingleSample = kNumChannelsForStereo * sizeof(int16_t); + +const double kPi = 3.141592653589; +const double kTwoPi = 2.0 * kPi; + +class MyInstance : public pp::Instance { + private: + pp::Audio audio_; + uint32_t obtained_sample_frame_count_; + double audio_wave_time_; // between -kTwoPi, +kTwoPi + uint32_t duration_; // in msec + uint32_t frequency_; + + static void SoundCallback(void* samples, uint32_t num_bytes, void* thiz) { + MyInstance* instance = reinterpret_cast<MyInstance*>(thiz); + // CHECK inside callback is only for testing purposes. + CHECK(instance->obtained_sample_frame_count_ * kSizeSingleSample == + num_bytes); + const double delta = kTwoPi * instance->frequency_ / kSampleFrequency; + const int16_t max_int16 = std::numeric_limits<int16_t>::max(); + int16_t* buf = reinterpret_cast<int16_t*>(samples); + for (size_t i = 0; i < instance->obtained_sample_frame_count_; ++i) { + const double v = sin(instance->audio_wave_time_) * max_int16; + *buf++ = static_cast<int16_t>(v); + *buf++ = static_cast<int16_t>(v); + // Add delta, keep within -kTwoPi, +TwoPi to preserve precision. + instance->audio_wave_time_ += delta; + if (instance->audio_wave_time_ > kTwoPi) + instance->audio_wave_time_ -= kTwoPi * 2.0; + } + } + + static void StopOutput(void* thiz, int32_t err) { + if (PP_OK == err) { + MyInstance* instance = static_cast<MyInstance*>(thiz); + instance->audio_.StopPlayback(); + } + } + + void ExtraChecks(pp::AudioConfig* config) { + CHECK(obtained_sample_frame_count_ >= PP_AUDIOMINSAMPLEFRAMECOUNT); + CHECK(obtained_sample_frame_count_ <= PP_AUDIOMAXSAMPLEFRAMECOUNT); + + PPB_GetInterface get_browser_if = + pp::Module::Get()->get_browser_interface(); + + const struct PPB_AudioConfig* audio_config_if = + static_cast<const struct PPB_AudioConfig*>( + get_browser_if(PPB_AUDIO_CONFIG_INTERFACE)); + + const struct PPB_Audio* audio_if = + static_cast<const struct PPB_Audio*>( + get_browser_if(PPB_AUDIO_INTERFACE)); + + CHECK(NULL != audio_config_if); + CHECK(NULL != audio_if); + + const PP_Resource audio_config_res = config->pp_resource(); + const PP_Resource audio_res = audio_.pp_resource(); + + CHECK(PP_TRUE == audio_config_if->IsAudioConfig(audio_config_res)); + CHECK(PP_TRUE == audio_if->IsAudio(audio_res)); + CHECK(PP_FALSE == audio_config_if->IsAudioConfig(audio_res)); + CHECK(PP_FALSE == audio_if->IsAudio(audio_config_res)); + CHECK(audio_if->GetCurrentConfig(audio_res) == audio_config_res); + CHECK(0 == audio_if->GetCurrentConfig(audio_config_res)); + CHECK(audio_config_if->GetSampleRate(audio_config_res) == + config->sample_rate()); + CHECK(audio_config_if->GetSampleFrameCount(audio_config_res) == + config->sample_frame_count()); + CHECK(audio_.config().pp_resource() == audio_config_res); + } + + void ParseArgs(uint32_t argc, const char* argn[], const char* argv[]) { + for (uint32_t i = 0; i < argc; ++i) { + const std::string tag = argn[i]; + if (tag == "duration") duration_ = strtol(argv[i], 0, 0); + if (tag == "frequency") frequency_ = strtol(argv[i], 0, 0); + } + } + + public: + explicit MyInstance(PP_Instance instance) + : pp::Instance(instance), + duration_(kDefaultDuration), frequency_(kDefaultFrequency) {} + + virtual ~MyInstance() {} + + virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) { + ParseArgs(argc, argn, argv); + obtained_sample_frame_count_ = pp::AudioConfig::RecommendSampleFrameCount( + kSampleFrequency, kSampleFrameCount); + + pp::AudioConfig config = + pp::AudioConfig(this, kSampleFrequency, obtained_sample_frame_count_); + + audio_ = pp::Audio(this, config, SoundCallback, this); + + ExtraChecks(&config); + + CHECK(audio_.StartPlayback()); + + pp::CompletionCallback cc(StopOutput, this); + pp::Module::Get()->core()->CallOnMainThread(duration_, cc, PP_OK); + return true; + } +}; + +// standard boilerplate code below +class MyModule : public pp::Module { + public: + virtual pp::Instance* CreateInstance(PP_Instance instance) { + return new MyInstance(instance); + } +}; + +namespace pp { +Module* CreateModule() { + return new MyModule(); +} + +} // namespace pp diff --git a/ppapi/native_client/tests/ppapi_simple_tests/audio.stdin b/ppapi/native_client/tests/ppapi_simple_tests/audio.stdin new file mode 100644 index 0000000..9f87ff1 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_simple_tests/audio.stdin @@ -0,0 +1,116 @@ +# NOTE: to be used with a prolog from +# tests/ppapi_proxy/sel_universal_ppapi_replay_prolog.stdin + +# define a bunch of variables for readability +set_variable MODULE i(4444) +set_variable INSTANCE i(5555) +# to be safe we allocate a shmem region of 64k +set_variable SHM_SIZE 65536 +set_variable NUM_FRAMES 4096 +# size of the audio buffer = NUM_FRAMES * 2 (channels) * 2 (16bit audio) +set_variable BUF_SIZE 16384 +# SHM_UNUSED = SHM_SIZE - BUF_SIZE +set_variable SHM_UNUSED 49152 + +# arbitrary numbers we picked as handles +set_variable HANDLE_CFG i(30) +set_variable HANDLE_AUDIO i(34) + +echo +echo "*** INIT MODULE" +# PPB_xxx replays below will be triggered as a reaction to PPP_InitializeModule +replay 1 PPB_GetInterface:s:i s("PPB_Core;1.0") * i(1) +# The results contain a process id which is non-determinisitic. +# We must hide the results to support golden file diffing. +rpc PPP_InitializeModule hide-results i(0) ${MODULE} h(pepper_desc) s("${service_string}") * i(0) i(0) + +echo +echo "*** INIT INSTANCE" +set_variable TAGS C(10,frequency\000) +set_variable VALUES C(4,800\000) +# The PPB_xxx replays below will be triggered as a reaction to +# PPP_Instance_DidCreate in roughly the order shown +replay 1 PPB_GetInterface:s:i s("PPB_AudioConfig;1.0") * i(1) +replay 1 PPB_AudioConfig_RecommendSampleFrameCount:ii:i i(44100) i(${NUM_FRAMES}) * i(${NUM_FRAMES}) +replay 1 PPB_AudioConfig_CreateStereo16Bit:iii:i ${INSTANCE} i(44100) i(${NUM_FRAMES}) * ${HANDLE_CFG} +# TODO(robertm): explain why these are called three times +replay 3 PPB_Core_AddRefResource:i: ${HANDLE_CFG} * +replay 3 PPB_Core_ReleaseResource:i: ${HANDLE_CFG} * +replay 1 PPB_GetInterface:s:i s("PPB_Audio;1.0") * i(1) +replay 1 PPB_Audio_Create:ii:i ${INSTANCE} ${HANDLE_CFG} * ${HANDLE_AUDIO} +replay 1 PPB_AudioConfig_IsAudioConfig:i:i ${HANDLE_CFG} * i(1) +replay 1 PPB_Audio_IsAudio:i:i ${HANDLE_AUDIO} * i(1) +replay 1 PPB_AudioConfig_IsAudioConfig:i:i ${HANDLE_AUDIO} * i(0) +replay 1 PPB_Audio_IsAudio:i:i ${HANDLE_CFG} * i(0) +replay 1 PPB_Audio_GetCurrentConfig:i:i ${HANDLE_AUDIO} * ${HANDLE_CFG} +replay 1 PPB_Audio_GetCurrentConfig:i:i ${HANDLE_CFG} * i(0) +replay 1 PPB_AudioConfig_GetSampleRate:i:i ${HANDLE_CFG} * i(44100) +replay 1 PPB_AudioConfig_GetSampleFrameCount:i:i ${HANDLE_CFG} * i(${NUM_FRAMES}) +replay 1 PPB_Audio_StartPlayback:i:i ${HANDLE_AUDIO} * i(1) +replay 1 PPB_Core_CallOnMainThread:iii: i(10000) i(1) i(0) * +rpc PPP_Instance_DidCreate ${INSTANCE} i(1) ${TAGS} ${VALUES} * i(0) + +echo +echo "*** TRIGGER REPAINT" +rpc PPP_Instance_DidChangeView ${INSTANCE} I(4,8,79,400,400) I(4,0,0,400,400) * + +echo +echo "*** SETTING UP AUDIO SHARED MEMORY" +shmem audio_handle audio_address ${SHM_SIZE} +memset ${audio_address} 0 ${SHM_SIZE} 0 +checksum ${audio_address} 0 ${SHM_SIZE} + +echo +echo "*** SETTING UP AUDIO SYNC SOCKET" +sync_socket_create sync_in sync_out + +echo +echo "*** AUDIO STREAM" +# inform the nexe about the shmem region and the sync_socket +rpc PPP_Audio_StreamCreated ${HANDLE_AUDIO} h(audio_handle) i(${BUF_SIZE}) h(sync_out) * + +echo +echo "*** AUDIO STREAM SYNC" +# By writing a byte into the sync sock we wake up the other side, the actual +# value does not matter as long as it is not -1. +# once the other side has woken up it is supposed to write into the buffer +# associated with audio_handle as quickly as possible. +# We wait 1sec to give it time to do that. +# Note: the shmem area is actually bigger than the buffer. +# We compute a checksum over the part that is used and that isn't. +# The latter checksum should not change and be zero. +sync_socket_write sync_in 0 +sleep 1 +checksum ${audio_address} 0 ${BUF_SIZE} +checksum ${audio_address} ${BUF_SIZE} ${SHM_UNUSED} + +echo +echo "*** AUDIO STREAM SYNC" +sync_socket_write sync_in 1 +sleep 1 +checksum ${audio_address} 0 ${BUF_SIZE} +checksum ${audio_address} ${BUF_SIZE} ${SHM_UNUSED} + +echo +echo "*** AUDIO STREAM SYNC" +sync_socket_write sync_in 2 +sleep 1 +checksum ${audio_address} 0 ${BUF_SIZE} +checksum ${audio_address} ${BUF_SIZE} ${SHM_UNUSED} + +echo +echo "*** AUDIO STREAM SYNC" + +sync_socket_write sync_in 3 +sleep 1 +checksum ${audio_address} 0 ${BUF_SIZE} +checksum ${audio_address} ${BUF_SIZE} ${SHM_UNUSED} + +echo +echo "*** TERMINATE AUDIO STREAM" +sync_socket_write sync_in -1 +checksum ${audio_address} 0 ${BUF_SIZE} +checksum ${audio_address} ${BUF_SIZE} 49152 + +sleep 1 +rpc PPP_ShutdownModule * diff --git a/ppapi/native_client/tests/ppapi_simple_tests/audio.stdout b/ppapi/native_client/tests/ppapi_simple_tests/audio.stdout new file mode 100644 index 0000000..f50d868 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_simple_tests/audio.stdout @@ -0,0 +1,131 @@ + +"*** REPLAY PROLOG" + +"*** REGISTER REPLAY METHODS" + +"*** CREATE UPCALL SERVICE" + +"*** INIT MODULE" +rpc call intiated PPP_InitializeModule:iihs:ii +input 0: i(0) +input 1: i(4444) +input 2: h(pepper_desc) +input 3: @LENGTHY_SERVICE_STRING +replaying PPB_GetInterface:s:i: +input 0: s("PPB_Core;1.0") +output 0: i(1) +rpc call complete PPP_InitializeModule:iihs:ii + + +"*** INIT INSTANCE" +rpc call intiated PPP_Instance_DidCreate:iiCC:i +input 0: i(5555) +input 1: i(1) +input 2: C(10,frequency\x00) +input 3: C(4,800\x00) +replaying PPB_GetInterface:s:i: +input 0: s("PPB_AudioConfig;1.0") +output 0: i(1) +replaying PPB_AudioConfig_RecommendSampleFrameCount:ii:i: +input 0: i(44100) +input 1: i(4096) +output 0: i(4096) +replaying PPB_AudioConfig_CreateStereo16Bit:iii:i: +input 0: i(5555) +input 1: i(44100) +input 2: i(4096) +output 0: i(30) +replaying PPB_Core_AddRefResource:i:: +input 0: i(30) +replaying PPB_GetInterface:s:i: +input 0: s("PPB_Audio;1.0") +output 0: i(1) +replaying PPB_Audio_Create:ii:i: +input 0: i(5555) +input 1: i(30) +output 0: i(34) +replaying PPB_Core_AddRefResource:i:: +input 0: i(30) +replaying PPB_Core_ReleaseResource:i:: +input 0: i(30) +replaying PPB_AudioConfig_IsAudioConfig:i:i: +input 0: i(30) +output 0: i(1) +replaying PPB_Audio_IsAudio:i:i: +input 0: i(34) +output 0: i(1) +replaying PPB_AudioConfig_IsAudioConfig:i:i: +input 0: i(34) +output 0: i(0) +replaying PPB_Audio_IsAudio:i:i: +input 0: i(30) +output 0: i(0) +replaying PPB_Audio_GetCurrentConfig:i:i: +input 0: i(34) +output 0: i(30) +replaying PPB_Audio_GetCurrentConfig:i:i: +input 0: i(30) +output 0: i(0) +replaying PPB_AudioConfig_GetSampleRate:i:i: +input 0: i(30) +output 0: i(44100) +replaying PPB_AudioConfig_GetSampleFrameCount:i:i: +input 0: i(30) +output 0: i(4096) +replaying PPB_Audio_StartPlayback:i:i: +input 0: i(34) +output 0: i(1) +replaying PPB_Core_CallOnMainThread:iii:: +input 0: i(10000) +input 1: i(1) +input 2: i(0) +replaying PPB_Core_ReleaseResource:i:: +input 0: i(30) +rpc call complete PPP_Instance_DidCreate:iiCC:i +output 0: i(1) + + +"*** TRIGGER REPAINT" +rpc call intiated PPP_Instance_DidChangeView:iII: +input 0: i(5555) +input 1: I(4,8,79,400,400) +input 2: I(4,0,0,400,400) +rpc call complete PPP_Instance_DidChangeView:iII: + + +"*** SETTING UP AUDIO SHARED MEMORY" +CHECKSUM: 0x00000000 + +"*** SETTING UP AUDIO SYNC SOCKET" + +"*** AUDIO STREAM" +rpc call intiated PPP_Audio_StreamCreated:ihih: +input 0: i(34) +input 1: h(audio_handle) +input 2: i(16384) +input 3: h(sync_out) +rpc call complete PPP_Audio_StreamCreated:ihih: + + +"*** AUDIO STREAM SYNC" +CHECKSUM: 0xbbf21e00 +CHECKSUM: 0x00000000 + +"*** AUDIO STREAM SYNC" +CHECKSUM: 0xcbef91ac +CHECKSUM: 0x00000000 + +"*** AUDIO STREAM SYNC" +CHECKSUM: 0xd0f22174 +CHECKSUM: 0x00000000 + +"*** AUDIO STREAM SYNC" +CHECKSUM: 0x23742c68 +CHECKSUM: 0x00000000 + +"*** TERMINATE AUDIO STREAM" +CHECKSUM: 0x23742c68 +CHECKSUM: 0x00000000 +rpc call intiated PPP_ShutdownModule:: +rpc call complete PPP_ShutdownModule:: + diff --git a/ppapi/native_client/tests/ppapi_simple_tests/event.cc b/ppapi/native_client/tests/ppapi_simple_tests/event.cc new file mode 100644 index 0000000..30b4f91 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_simple_tests/event.cc @@ -0,0 +1,250 @@ +// 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 <stdint.h> +#include <stdlib.h> + +#include <sstream> +#include <string> +#include <queue> + +#include "ppapi/c/pp_input_event.h" +#include "ppapi/c/ppp_input_event.h" +#include "ppapi/cpp/instance.h" +#include "ppapi/cpp/module.h" +#include "ppapi/cpp/point.h" +#include "ppapi/cpp/var.h" +#include "ppapi/cpp/input_event.h" + + +using std::string; +using std::queue; +using std::ostringstream; + +const int kDefaultEventBufferSize = 10; + +namespace { + +string ModifierToString(uint32_t modifier) { + string s; + if (modifier & PP_INPUTEVENT_MODIFIER_SHIFTKEY) { + s += "shift "; + } + if (modifier & PP_INPUTEVENT_MODIFIER_CONTROLKEY) { + s += "ctrl "; + } + if (modifier & PP_INPUTEVENT_MODIFIER_ALTKEY) { + s += "alt "; + } + if (modifier & PP_INPUTEVENT_MODIFIER_METAKEY) { + s += "meta "; + } + if (modifier & PP_INPUTEVENT_MODIFIER_ISKEYPAD) { + s += "keypad "; + } + if (modifier & PP_INPUTEVENT_MODIFIER_ISAUTOREPEAT) { + s += "autorepeat "; + } + if (modifier & PP_INPUTEVENT_MODIFIER_LEFTBUTTONDOWN) { + s += "left-button-down "; + } + if (modifier & PP_INPUTEVENT_MODIFIER_MIDDLEBUTTONDOWN) { + s += "middle-button-down "; + } + if (modifier & PP_INPUTEVENT_MODIFIER_RIGHTBUTTONDOWN) { + s += "right-button-down "; + } + if (modifier & PP_INPUTEVENT_MODIFIER_CAPSLOCKKEY) { + s += "caps-lock "; + } + if (modifier & PP_INPUTEVENT_MODIFIER_NUMLOCKKEY) { + s += "num-lock "; + } + return s; +} + + +string MouseButtonToString(PP_InputEvent_MouseButton button) { + switch (button) { + case PP_INPUTEVENT_MOUSEBUTTON_NONE: + return "None"; + case PP_INPUTEVENT_MOUSEBUTTON_LEFT: + return "Left"; + case PP_INPUTEVENT_MOUSEBUTTON_MIDDLE: + return "Middle"; + case PP_INPUTEVENT_MOUSEBUTTON_RIGHT: + return "Right"; + default: + ostringstream stream; + stream << "Unrecognized (" << static_cast<int32_t>(button) << ")"; + return stream.str(); + } +} + + +string KeyEvent(const pp::KeyboardInputEvent& key_event, + const string& kind) { + ostringstream stream; + stream << "Key event:" << kind + << " modifier:" << ModifierToString(key_event.GetModifiers()) + << " key_code:" << key_event.GetKeyCode() + << " time:" << key_event.GetTimeStamp() + << " text:" << key_event.GetCharacterText().DebugString() + << "\n"; + return stream.str(); +} + + +string MouseEvent(const pp::MouseInputEvent& mouse_event, + const string& kind) { + ostringstream stream; + stream << "Mouse event:" << kind + << " modifier:" << ModifierToString(mouse_event.GetModifiers()) + << " button:" << MouseButtonToString(mouse_event.GetButton()) + << " x:" << mouse_event.GetPosition().x() + << " y:" << mouse_event.GetPosition().y() + << " click_count:" << mouse_event.GetClickCount() + << " time:" << mouse_event.GetTimeStamp() + << "\n"; + return stream.str(); +} + + +string WheelEvent(const pp::WheelInputEvent& wheel_event) { + ostringstream stream; + stream << "Wheel event." + << " modifier:" << ModifierToString(wheel_event.GetModifiers()) + << " deltax:" << wheel_event.GetDelta().x() + << " deltay:" << wheel_event.GetDelta().y() + << " wheel_ticks_x:" << wheel_event.GetTicks().x() + << " wheel_ticks_y:" << wheel_event.GetTicks().y() + << " scroll_by_page:" + << (wheel_event.GetScrollByPage() ? "true" : "false") + << "\n"; + return stream.str(); +} + + +string EventToString(const pp::InputEvent& event) { + ostringstream stream; + switch (event.GetType()) { + default: + case PP_INPUTEVENT_TYPE_UNDEFINED: + stream << "Unrecognized Event (" << static_cast<int32_t>(event.GetType()) + << ")"; + return stream.str(); + + case PP_INPUTEVENT_TYPE_MOUSEDOWN: + return MouseEvent(pp::MouseInputEvent(event), "Down"); + case PP_INPUTEVENT_TYPE_MOUSEUP: + return MouseEvent(pp::MouseInputEvent(event), "Up"); + case PP_INPUTEVENT_TYPE_MOUSEMOVE: + return MouseEvent(pp::MouseInputEvent(event), "Move"); + case PP_INPUTEVENT_TYPE_MOUSEENTER: + return MouseEvent(pp::MouseInputEvent(event), "Enter"); + case PP_INPUTEVENT_TYPE_MOUSELEAVE: + return MouseEvent(pp::MouseInputEvent(event), "Leave"); + + case PP_INPUTEVENT_TYPE_WHEEL: + return WheelEvent(pp::WheelInputEvent(event)); + + case PP_INPUTEVENT_TYPE_RAWKEYDOWN: + return KeyEvent(pp::KeyboardInputEvent(event), "RawKeyDown"); + case PP_INPUTEVENT_TYPE_KEYDOWN: + return KeyEvent(pp::KeyboardInputEvent(event), "Down"); + case PP_INPUTEVENT_TYPE_KEYUP: + return KeyEvent(pp::KeyboardInputEvent(event), "Up"); + case PP_INPUTEVENT_TYPE_CHAR: + return KeyEvent(pp::KeyboardInputEvent(event), "Char"); + } +} + +void StringReplace(string* input, + const string& find, + const string& replace) { + if (find.length() == 0 || input->length() == 0) { + return; + } + + size_t start_pos = 0; + while (1) { + start_pos = input->find(find, start_pos); + if (start_pos == string::npos) { + break; + } + input->replace(start_pos, find.length(), replace); + start_pos += replace.length(); + } +} + +} // namespace + + +class MyInstance : public pp::Instance { + private: + size_t max_buffer_size_; + queue<string> event_buffer_; + + void ParseArgs(uint32_t argc, const char* argn[], const char* argv[]) { + for (uint32_t i = 0; i < argc; ++i) { + const std::string tag = argn[i]; + if (tag == "buffer_size") max_buffer_size_ = strtol(argv[i], 0, 0); + // ignore other tags + } + } + + // Dump all the event via PostMessage for testing + void FlushEventBuffer() { + while (event_buffer_.size() > 0) { + string s = event_buffer_.front(); + event_buffer_.pop(); + // Replace space with underscore to simplify testing + StringReplace(&s, " ", "_"); + pp::Var message(s); + PostMessage(message); + } + } + + public: + explicit MyInstance(PP_Instance instance) + : pp::Instance(instance), max_buffer_size_(kDefaultEventBufferSize) { + RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE | PP_INPUTEVENT_CLASS_WHEEL); + RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_KEYBOARD); + } + + virtual ~MyInstance() {} + + virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) { + ParseArgs(argc, argn, argv); + return true; + } + + virtual bool HandleInputEvent(const pp::InputEvent& event) { + ostringstream stream; + stream << pp_instance() << ": " << EventToString(event); + event_buffer_.push(stream.str()); + if (event_buffer_.size() >= max_buffer_size_) { + FlushEventBuffer(); + } + return true; + } + + virtual void DidChangeFocus(bool has_focus) { + FlushEventBuffer(); + } +}; + +// standard boilerplate code below +class MyModule : public pp::Module { + public: + virtual pp::Instance* CreateInstance(PP_Instance instance) { + return new MyInstance(instance); + } +}; + +namespace pp { + Module* CreateModule() { + return new MyModule(); + } +} diff --git a/ppapi/native_client/tests/ppapi_simple_tests/event.stdin b/ppapi/native_client/tests/ppapi_simple_tests/event.stdin new file mode 100644 index 0000000..ed0a556 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_simple_tests/event.stdin @@ -0,0 +1,133 @@ +# define a bunch of variables for readability + +set_variable MODULE i(4444) +set_variable INSTANCE i(5555) +set_variable EVENT i(6666) + +# NOTE: the event interface between the nexe and proxy is not strictly +# following the ppapi model because of performance reasons. +# +# The nexe entry point is +# PPP_InputEvent_HandleInputEvent:iiCC:i +# Where the arguments are: +# in: +# PP_Instance instance: +# PP_Resource resource: +# InputEventData event_data: +# char[] character_text: +# out: +# int handled: +# +# InputEventData is described in src/shared/ppapi_proxy/input_event_data.h as: +# +# struct InputEventData { +# InputEventData(); +# ~InputEventData(); +# +# PP_InputEvent_Type event_type; +# uint32_t event_modifiers; +# PP_TimeTicks event_time_stamp; +# +# PP_InputEvent_MouseButton mouse_button; +# int32_t mouse_click_count; +# PP_Point mouse_position; +# +# PP_FloatPoint wheel_delta; +# PP_FloatPoint wheel_ticks; +# PP_Bool wheel_scroll_by_page; +# +# uint32_t key_code; +# }; + +# ieee double +set_variable TIME_1 8:0x3ff0000000000000 +set_variable TIME_2 8:0x3ff1000000000000 +set_variable TIME_3 8:0x3ff2000000000000 +set_variable TIME_4 8:0x3ff3000000000000 +set_variable TIME_5 8:0x3ff4000000000000 +set_variable TIME_6 8:0x3ff5000000000000 +set_variable TIME_7 8:0x3ff6000000000000 + +# pair of ints +set_variable COORDS 4:264,4:100 + +set_variable EV_MOUSE_DOWN R(56,4:0,4:64,${TIME_1},4:0,4:1,${COORDS},8:0,8:0,4:0,4:0) +set_variable EV_MOUSE_UP R(56,4:1,4:64,${TIME_2},4:0,4:0,${COORDS},8:0,8:0,4:0,4:0) + +set_variable EV_MOUSE_MOVE R(56,4:2,4:0,${TIME_3},4:0,4:0,${COORDS},8:0,8:0,4:0,4:0) + +set_variable EV_MOUSE_ENTER R(56,4:3,4:0,${TIME_4},4:0,4:0,${COORDS},8:0,8:0,4:0,4:0) +set_variable EV_MOUSE_LEAVE R(56,4:4,4:0,${TIME_5},4:0,4:0,${COORDS},8:0,8:0,4:0,4:0) + +set_variable EV_KEY_DOWN R(56,4:7,4:0,${TIME_6},4:0,4:0,8:0,8:0,8:0,4:0,4:0x54) +set_variable EV_KEY_UP R(56,4:8,4:0,${TIME_7},4:0,4:0,8:0,8:0,8:0,4:0,4:0x54) + +set_variable JS_STR 4:5 +set_variable JS_UND 4:0 +set_variable VAR_UNDEF R(8,${JS_UND},4:0) +set_variable VAR_CHAR R(16,${JS_STR},4:1,8:0x56) + + +echo +echo "*** INIT MODULE" +replay 1 PPB_GetInterface:s:i s("PPB_Core;1.0") * i(1) +replay 1 PPB_GetInterface:s:i s("PPB_Instance;1.0") * i(1) +# the results contain a process id which is non-determinisitic +rpc PPP_InitializeModule hide-results i(0) ${MODULE} h(pepper_desc) s("${service_string}") * i(0) i(0) + + +echo +echo "*** INIT INSTANCE" +set_variable TAGS C(12,buffer_size\000) +set_variable VALUES C(4,100\000) +replay 1 PPB_GetInterface:s:i s("PPB_InputEvent;1.0") * i(1) +rpc PPP_Instance_DidCreate ${INSTANCE} i(1) ${TAGS} ${VALUES} * i(0) + +replay 1 PPB_GetInterface:s:i s("PPB_Var;1.0") * i(1) +replay 1 PPB_GetInterface:s:i s("PPB_MouseInputEvent;1.0") * i(1) +replay 1 PPB_GetInterface:s:i s("PPB_KeyboardInputEvent;1.0") * i(1) +# These occur once each for each event sent to the nexe +replay 7 PPB_Core_AddRefResource:i: ${EVENT} * +replay 7 ReleaseResourceMultipleTimes:ii: ${EVENT} i(1) * + + +echo +echo "*** SENT EVENTS EV_MOUSE_DOWN" +rpc PPP_InputEvent_HandleInputEvent ${INSTANCE} ${EVENT} ${EV_MOUSE_DOWN} ${VAR_UNDEF} * i(0) +echo +echo "*** SENT EVENTS EV_MOUSE_UP" +rpc PPP_InputEvent_HandleInputEvent ${INSTANCE} ${EVENT} ${EV_MOUSE_UP} ${VAR_UNDEF} * i(0) +echo +echo "*** SENT EVENTS EV_MOUSE_MOVE" +rpc PPP_InputEvent_HandleInputEvent ${INSTANCE} ${EVENT} ${EV_MOUSE_MOVE} ${VAR_UNDEF} * i(0) +echo +echo "*** SENT EVENTS EV_MOUSE_ENTER" +rpc PPP_InputEvent_HandleInputEvent ${INSTANCE} ${EVENT} ${EV_MOUSE_ENTER} ${VAR_UNDEF} * i(0) +echo +echo "*** SENT EVENTS EV_MOUSE_LEAVE" +rpc PPP_InputEvent_HandleInputEvent ${INSTANCE} ${EVENT} ${EV_MOUSE_LEAVE} ${VAR_UNDEF} * i(0) +echo +echo "*** SENT EVENTS EV_KEY_UP" +rpc PPP_InputEvent_HandleInputEvent ${INSTANCE} ${EVENT} ${EV_KEY_UP} ${VAR_CHAR} * i(0) +echo +echo "*** SENT EVENTS EV_KEY_DOWN" +rpc PPP_InputEvent_HandleInputEvent ${INSTANCE} ${EVENT} ${EV_KEY_DOWN} ${VAR_CHAR} * i(0) + + +echo +echo "*** TRIGGER EVENT FLUSH" +replay 1 PPB_GetInterface:s:i s("PPB_Var;1.0") * i(1) +replay 1 PPB_GetInterface:s:i s("PPB_Messaging;1.0") * i(1) +replay 1 PPB_Messaging_PostMessage:iC: i(5555) C(104,\x05\x00\x00\x00_\x00\x00\x005555:_Mouse_event:Down_modifier:left-button-down__button:Left_x:264_y:100_click_count:1_time:1\n\x00) * +replay 1 PPB_Messaging_PostMessage:iC: i(5555) C(112,\x05\x00\x00\x00b\x00\x00\x005555:_Mouse_event:Up_modifier:left-button-down__button:Left_x:264_y:100_click_count:0_time:1.0625\n\x00\x00\x00\x00\x00\x00) * +replay 1 PPB_Messaging_PostMessage:iC: i(5555) C(96,\x05\x00\x00\x00R\x00\x00\x005555:_Mouse_event:Move_modifier:_button:Left_x:264_y:100_click_count:0_time:1.125\n\x00\x00\x00\x00\x00\x00) * +replay 1 PPB_Messaging_PostMessage:iC: i(5555) C(96,\x05\x00\x00\x00T\x00\x00\x005555:_Mouse_event:Enter_modifier:_button:Left_x:264_y:100_click_count:0_time:1.1875\n\x00\x00\x00\x00) * +replay 1 PPB_Messaging_PostMessage:iC: i(5555) C(96,\x05\x00\x00\x00R\x00\x00\x005555:_Mouse_event:Leave_modifier:_button:Left_x:264_y:100_click_count:0_time:1.25\n\x00\x00\x00\x00\x00\x00) * +replay 1 PPB_Messaging_PostMessage:iC: i(5555) C(80,\x05\x00\x00\x00B\x00\x00\x005555:_Key_event:Up_modifier:_key_code:84_time:1.375_text:Var<'V'>\n\x00\x00\x00\x00\x00\x00) * +replay 1 PPB_Messaging_PostMessage:iC: i(5555) C(80,\x05\x00\x00\x00E\x00\x00\x005555:_Key_event:Down_modifier:_key_code:84_time:1.3125_text:Var<'V'>\n\x00\x00\x00) * +rpc PPP_Instance_DidChangeFocus ${INSTANCE} b(0) * + + +rpc PPP_ShutdownModule * + +echo "DONE" diff --git a/ppapi/native_client/tests/ppapi_simple_tests/event.stdout b/ppapi/native_client/tests/ppapi_simple_tests/event.stdout new file mode 100644 index 0000000..ddc552b --- /dev/null +++ b/ppapi/native_client/tests/ppapi_simple_tests/event.stdout @@ -0,0 +1,180 @@ + +"*** REPLAY PROLOG" + +"*** REGISTER REPLAY METHODS" + +"*** CREATE UPCALL SERVICE" + +"*** INIT MODULE" +rpc call intiated PPP_InitializeModule:iihs:ii +input 0: i(0) +input 1: i(4444) +input 2: h(pepper_desc) +input 3: @LENGTHY_SERVICE_STRING +replaying PPB_GetInterface:s:i: +input 0: s("PPB_Core;1.0") +output 0: i(1) +rpc call complete PPP_InitializeModule:iihs:ii + + +"*** INIT INSTANCE" +rpc call intiated PPP_Instance_DidCreate:iiCC:i +input 0: i(5555) +input 1: i(1) +input 2: C(12,buffer_size\x00) +input 3: C(4,100\x00) +replaying PPB_GetInterface:s:i: +input 0: s("PPB_InputEvent;1.0") +output 0: i(1) +rpc call complete PPP_Instance_DidCreate:iiCC:i +output 0: i(1) + + +"*** SENT EVENTS EV_MOUSE_DOWN" +rpc call intiated PPP_InputEvent_HandleInputEvent:iiCC:i +input 0: i(5555) +input 1: i(6666) +input 2: C(56,\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x01\x00\x00\x00\b\x01\x00\x00d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00) +input 3: C(8,\x00\x00\x00\x00\x00\x00\x00\x00) +replaying PPB_Core_AddRefResource:i:: +input 0: i(6666) +replaying PPB_GetInterface:s:i: +input 0: s("PPB_MouseInputEvent;1.0") +output 0: i(1) +replaying ReleaseResourceMultipleTimes:ii:: +input 0: i(6666) +input 1: i(1) +replaying PPB_GetInterface:s:i: +input 0: s("PPB_Var;1.0") +output 0: i(1) +rpc call complete PPP_InputEvent_HandleInputEvent:iiCC:i +output 0: i(1) + + +"*** SENT EVENTS EV_MOUSE_UP" +rpc call intiated PPP_InputEvent_HandleInputEvent:iiCC:i +input 0: i(5555) +input 1: i(6666) +input 2: C(56,\x01\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1?\x00\x00\x00\x00\x00\x00\x00\x00\b\x01\x00\x00d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00) +input 3: C(8,\x00\x00\x00\x00\x00\x00\x00\x00) +replaying PPB_Core_AddRefResource:i:: +input 0: i(6666) +replaying ReleaseResourceMultipleTimes:ii:: +input 0: i(6666) +input 1: i(1) +rpc call complete PPP_InputEvent_HandleInputEvent:iiCC:i +output 0: i(1) + + +"*** SENT EVENTS EV_MOUSE_MOVE" +rpc call intiated PPP_InputEvent_HandleInputEvent:iiCC:i +input 0: i(5555) +input 1: i(6666) +input 2: C(56,\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf2?\x00\x00\x00\x00\x00\x00\x00\x00\b\x01\x00\x00d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00) +input 3: C(8,\x00\x00\x00\x00\x00\x00\x00\x00) +replaying PPB_Core_AddRefResource:i:: +input 0: i(6666) +replaying ReleaseResourceMultipleTimes:ii:: +input 0: i(6666) +input 1: i(1) +rpc call complete PPP_InputEvent_HandleInputEvent:iiCC:i +output 0: i(1) + + +"*** SENT EVENTS EV_MOUSE_ENTER" +rpc call intiated PPP_InputEvent_HandleInputEvent:iiCC:i +input 0: i(5555) +input 1: i(6666) +input 2: C(56,\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf3?\x00\x00\x00\x00\x00\x00\x00\x00\b\x01\x00\x00d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00) +input 3: C(8,\x00\x00\x00\x00\x00\x00\x00\x00) +replaying PPB_Core_AddRefResource:i:: +input 0: i(6666) +replaying ReleaseResourceMultipleTimes:ii:: +input 0: i(6666) +input 1: i(1) +rpc call complete PPP_InputEvent_HandleInputEvent:iiCC:i +output 0: i(1) + + +"*** SENT EVENTS EV_MOUSE_LEAVE" +rpc call intiated PPP_InputEvent_HandleInputEvent:iiCC:i +input 0: i(5555) +input 1: i(6666) +input 2: C(56,\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf4?\x00\x00\x00\x00\x00\x00\x00\x00\b\x01\x00\x00d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00) +input 3: C(8,\x00\x00\x00\x00\x00\x00\x00\x00) +replaying PPB_Core_AddRefResource:i:: +input 0: i(6666) +replaying ReleaseResourceMultipleTimes:ii:: +input 0: i(6666) +input 1: i(1) +rpc call complete PPP_InputEvent_HandleInputEvent:iiCC:i +output 0: i(1) + + +"*** SENT EVENTS EV_KEY_UP" +rpc call intiated PPP_InputEvent_HandleInputEvent:iiCC:i +input 0: i(5555) +input 1: i(6666) +input 2: C(56,\b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6?\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\x00\x00\x00) +input 3: C(16,\x05\x00\x00\x00\x01\x00\x00\x00V\x00\x00\x00\x00\x00\x00\x00) +replaying PPB_Core_AddRefResource:i:: +input 0: i(6666) +replaying PPB_GetInterface:s:i: +input 0: s("PPB_KeyboardInputEvent;1.0") +output 0: i(1) +replaying ReleaseResourceMultipleTimes:ii:: +input 0: i(6666) +input 1: i(1) +rpc call complete PPP_InputEvent_HandleInputEvent:iiCC:i +output 0: i(1) + + +"*** SENT EVENTS EV_KEY_DOWN" +rpc call intiated PPP_InputEvent_HandleInputEvent:iiCC:i +input 0: i(5555) +input 1: i(6666) +input 2: C(56,\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf5?\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\x00\x00\x00) +input 3: C(16,\x05\x00\x00\x00\x01\x00\x00\x00V\x00\x00\x00\x00\x00\x00\x00) +replaying PPB_Core_AddRefResource:i:: +input 0: i(6666) +replaying ReleaseResourceMultipleTimes:ii:: +input 0: i(6666) +input 1: i(1) +rpc call complete PPP_InputEvent_HandleInputEvent:iiCC:i +output 0: i(1) + + +"*** TRIGGER EVENT FLUSH" +rpc call intiated PPP_Instance_DidChangeFocus:ib: +input 0: i(5555) +input 1: b(0) +replaying PPB_GetInterface:s:i: +input 0: s("PPB_Messaging;1.0") +output 0: i(1) +replaying PPB_Messaging_PostMessage:iC:: +input 0: i(5555) +input 1: C(104,\x05\x00\x00\x00_\x00\x00\x005555:_Mouse_event:Down_modifier:left-button-down__button:Left_x:264_y:100_click_count:1_time:1\n\x00) +replaying PPB_Messaging_PostMessage:iC:: +input 0: i(5555) +input 1: C(112,\x05\x00\x00\x00b\x00\x00\x005555:_Mouse_event:Up_modifier:left-button-down__button:Left_x:264_y:100_click_count:0_time:1.0625\n\x00\x00\x00\x00\x00\x00) +replaying PPB_Messaging_PostMessage:iC:: +input 0: i(5555) +input 1: C(96,\x05\x00\x00\x00R\x00\x00\x005555:_Mouse_event:Move_modifier:_button:Left_x:264_y:100_click_count:0_time:1.125\n\x00\x00\x00\x00\x00\x00) +replaying PPB_Messaging_PostMessage:iC:: +input 0: i(5555) +input 1: C(96,\x05\x00\x00\x00T\x00\x00\x005555:_Mouse_event:Enter_modifier:_button:Left_x:264_y:100_click_count:0_time:1.1875\n\x00\x00\x00\x00) +replaying PPB_Messaging_PostMessage:iC:: +input 0: i(5555) +input 1: C(96,\x05\x00\x00\x00R\x00\x00\x005555:_Mouse_event:Leave_modifier:_button:Left_x:264_y:100_click_count:0_time:1.25\n\x00\x00\x00\x00\x00\x00) +replaying PPB_Messaging_PostMessage:iC:: +input 0: i(5555) +input 1: C(80,\x05\x00\x00\x00B\x00\x00\x005555:_Key_event:Up_modifier:_key_code:84_time:1.375_text:Var<'V'>\n\x00\x00\x00\x00\x00\x00) +replaying PPB_Messaging_PostMessage:iC:: +input 0: i(5555) +input 1: C(80,\x05\x00\x00\x00E\x00\x00\x005555:_Key_event:Down_modifier:_key_code:84_time:1.3125_text:Var<'V'>\n\x00\x00\x00) +rpc call complete PPP_Instance_DidChangeFocus:ib: + +rpc call intiated PPP_ShutdownModule:: +rpc call complete PPP_ShutdownModule:: + +"DONE" diff --git a/ppapi/native_client/tests/ppapi_simple_tests/file.cc b/ppapi/native_client/tests/ppapi_simple_tests/file.cc new file mode 100644 index 0000000..f0b9f83 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_simple_tests/file.cc @@ -0,0 +1,325 @@ +// 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 <stdint.h> +#include <stdlib.h> + +#include <iostream> +#include <sstream> +#include <string> +#include <queue> + +#include <nacl/nacl_check.h> + +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/ppb_file_io.h" + +#include "ppapi/cpp/completion_callback.h" +#include "ppapi/cpp/instance.h" +#include "ppapi/cpp/file_ref.h" +#include "ppapi/cpp/file_io.h" +#include "ppapi/cpp/module.h" +#include "ppapi/cpp/url_response_info.h" +#include "ppapi/cpp/url_loader.h" +#include "ppapi/cpp/url_request_info.h" +#include "ppapi/cpp/var.h" + +using std::string; +using std::ostringstream; + +const int kDefaultChunkSize = 1024; + + +class MyInstance : public pp::Instance { + private: + string url_; + bool stream_to_file_; + uint32_t chunk_size_; + bool debug_; + bool pdebug_; + + void ParseArgs(uint32_t argc, const char* argn[], const char* argv[]) { + for (uint32_t i = 0; i < argc; ++i) { + const std::string tag = argn[i]; + if (tag == "chunk_size") chunk_size_ = strtol(argv[i], 0, 0); + if (tag == "url") url_ = argv[i]; + if (tag == "to_file") stream_to_file_ = strtol(argv[i], 0, 0); + if (tag == "debug") debug_ = strtol(argv[i], 0, 0); + if (tag == "pdebug") pdebug_ = strtol(argv[i], 0, 0); + // ignore other tags + } + } + + public: + void Message(const string& s) { + ostringstream stream; + stream << pp_instance() << ": " << s; + pp::Var message(stream.str()); + PostMessage(message); + } + + + void Debug(const string& s) { + if (debug_) { + std::cout << "DEBUG: " << s; + } + if (pdebug_) { + Message("DEBUG: " + s); + } + } + + explicit MyInstance(PP_Instance instance) + : pp::Instance(instance), + url_("no_url_given.html"), + stream_to_file_(true), + chunk_size_(kDefaultChunkSize), + debug_(false), + pdebug_(false) { + } + + virtual ~MyInstance() {} + + // Defined below. This function does the real work by delegating it to + // either ReaderStreamAsFile or ReaderResponseBody + virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]); +}; + + + +class ReaderStreamAsFile { + private: + uint32_t current_offset_; + uint32_t chunk_size_; + char* buffer_; + pp::URLResponseInfo* response_info_; + pp::FileRef* file_ref_; + pp::FileIO* file_io_; + MyInstance* instance_; + pp::URLLoader loader_; + + // forward to instance + void Message(const string& s) { + instance_->Message(s); + } + + void Debug(const string& s) { + instance_->Debug(s); + } + + static void ReadCompleteCallback(void* thiz, int32_t result) { + ReaderStreamAsFile* reader = static_cast<ReaderStreamAsFile*>(thiz); + ostringstream stream; + stream << "ReadCompleteCallback Bytes Read: " << result; + reader->Debug(stream.str()); + if (result <= 0) { + reader->Message("COMPLETE"); + return; + } + + reader->current_offset_ += result; + reader->ReadMore(); + } + + void ReadMore() { + pp::CompletionCallback cc(ReadCompleteCallback, this); + cc.set_flags(PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); + int32_t rv = file_io_->Read(current_offset_, buffer_, chunk_size_, cc); + if (rv == PP_OK) { + cc.Run(rv); + } else if (rv != PP_OK_COMPLETIONPENDING) { + Message("Error: ReadMore unexpected rv"); + } + } + + static void OpenFileCompleteCallback(void* thiz, int32_t result) { + ReaderStreamAsFile* reader = static_cast<ReaderStreamAsFile*>(thiz); + + if (result != PP_OK) { + reader->Message("Error: FileOpenCompleteCallback unexpected result"); + return; + } + + reader->ReadMore(); + } + + void OpenFile() { + file_ref_ = new pp::FileRef(response_info_->GetBodyAsFileRef()); + CHECK(!file_ref_->is_null()); + + file_io_ = new pp::FileIO(instance_); + CHECK(!file_io_->is_null()); + + pp::CompletionCallback cc(OpenFileCompleteCallback, this); + int32_t rv = file_io_->Open(*file_ref_, PP_FILEOPENFLAG_READ, cc); + if (rv != PP_OK_COMPLETIONPENDING) { + Message("Error: OpenFile unexpected rv"); + } + } + + static void FinishCompleteCallback(void* thiz, int32_t result) { + ReaderStreamAsFile* reader = static_cast<ReaderStreamAsFile*>(thiz); + if (result != PP_OK) { + reader->Message("Error: FinishCompleteCallback unexpected result"); + return; + } + + reader->OpenFile(); + } + + void Finish() { + pp::CompletionCallback cc(FinishCompleteCallback, this); + cc.set_flags(PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); + int32_t rv = loader_.FinishStreamingToFile(cc); + if (rv == PP_OK) { + cc.Run(rv); + } else if (rv != PP_OK_COMPLETIONPENDING) { + Message("Error: Finish unexpected rv"); + } + } + + // this callback handles both regular and "stream-to-file" mode + // But control flow diverges afterwards + static void OpenURLCompleteCallback(void* thiz, int32_t result) { + ReaderStreamAsFile* reader = static_cast<ReaderStreamAsFile*>(thiz); + + reader->response_info_ = + new pp::URLResponseInfo(reader->loader_.GetResponseInfo()); + CHECK(!reader->response_info_->is_null()); + int32_t status_code = reader->response_info_->GetStatusCode(); + if (status_code != 200) { + reader->Message("Error: OpenURLCompleteCallback unexpected status code"); + return; + } + + reader->Finish(); + } + + void OpenURL(const string& url) { + pp::URLRequestInfo request(instance_); + request.SetURL(url); + request.SetStreamToFile(true); + + pp::CompletionCallback cc(OpenURLCompleteCallback, this); + int32_t rv = loader_.Open(request, cc); + if (rv != PP_OK_COMPLETIONPENDING) { + Message("Error: OpenURL unexpected rv"); + } + } + + public: + ReaderStreamAsFile(MyInstance* instance, + uint32_t chunk_size, + const string& url) : + current_offset_(0), + chunk_size_(chunk_size), + buffer_(new char[chunk_size]), + response_info_(0), + file_ref_(0), + file_io_(0), + instance_(instance), + loader_(instance) { + OpenURL(url); + } +}; + + +class ReaderResponseBody { + private: + uint32_t chunk_size_; + char* buffer_; + MyInstance* instance_; + pp::URLLoader loader_; + + // forward to instance + void Message(const string& s) { + instance_->Message(s); + } + + void Debug(const string& s) { + instance_->Debug(s); + } + + static void ReadCompleteCallback(void* thiz, int32_t result) { + ReaderResponseBody* reader = static_cast<ReaderResponseBody*>(thiz); + ostringstream stream; + stream << "ReadCompleteCallback Bytes Read: " << result; + reader->Debug(stream.str()); + if (result <= 0) { + reader->Message("COMPLETE"); + return; + } + reader->ReadMore(); + } + + void ReadMore() { + pp::CompletionCallback cc(ReadCompleteCallback, this); + cc.set_flags(PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); + int rv = loader_.ReadResponseBody(buffer_, chunk_size_, cc); + if (rv == PP_OK) { + cc.Run(rv); + } else if (rv != PP_OK_COMPLETIONPENDING) { + Message("Error: ReadMore unexpected rv"); + } + } + + static void LoadCompleteCallback(void* thiz, int32_t result) { + ReaderResponseBody* reader = static_cast<ReaderResponseBody*>(thiz); + ostringstream stream; + stream << "LoadCompleteCallback: " << result; + reader->Debug(stream.str()); + pp::URLResponseInfo response_info(reader->loader_.GetResponseInfo()); + CHECK(!response_info.is_null()); + int32_t status_code = response_info.GetStatusCode(); + if (status_code != 200) { + reader->Message("Error: LoadCompleteCallback unexpected status code"); + return; + } + + reader->ReadMore(); + } + + public: + ReaderResponseBody(MyInstance* instance, + uint32_t chunk_size, + const string& url) : + chunk_size_(chunk_size), + buffer_(new char[chunk_size]), + instance_(instance), + loader_(instance) { + pp::URLRequestInfo request(instance_); + request.SetURL(url); + request.SetStreamToFile(false); + + pp::CompletionCallback cc(LoadCompleteCallback, this); + int32_t rv = loader_.Open(request, cc); + if (rv != PP_OK_COMPLETIONPENDING) { + Message("Error: ReaderResponseBody: unexpected rv"); + } + } +}; + +// Defined here because of circular class visibility issues +bool MyInstance::Init(uint32_t argc, const char* argn[], const char* argv[]) { + ParseArgs(argc, argn, argv); + if (stream_to_file_) { + new ReaderStreamAsFile(this, chunk_size_, url_); + } else { + new ReaderResponseBody(this, chunk_size_, url_); + } + return true; +} + +// standard boilerplate code below +class MyModule : public pp::Module { + public: + virtual pp::Instance* CreateInstance(PP_Instance instance) { + return new MyInstance(instance); + } +}; + +namespace pp { + Module* CreateModule() { + return new MyModule(); + } +} diff --git a/ppapi/native_client/tests/ppapi_simple_tests/file1.stdin b/ppapi/native_client/tests/ppapi_simple_tests/file1.stdin new file mode 100644 index 0000000..31540d7 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_simple_tests/file1.stdin @@ -0,0 +1,86 @@ +# To be used with +# sel_universal_ppapi_replay_prolog.stdin +# define a bunch of variables for readability + +set_variable MODULE i(4444) +set_variable INSTANCE i(5555) + +# Tags used by pepper/srpc to marshall js parameters +set_variable JS_STR 4:5 +set_variable JS_INT 4:2 + +# NOTE: the strings below must not contain unescaped spaces or commas + +set_variable FILE_DATA1 C(6,hello\x20) +set_variable FILE_SIZE1 i(6) +set_variable FILE_DATA2 C(6,world!) +set_variable FILE_SIZE2 i(6) + +set_variable PARAM_STR_URL R(24,${JS_STR},4:10,"myurl.html",6:0) +set_variable PARAM_STR_GET R(16,${JS_STR},4:3,"GET",5:0) +set_variable PARAM_NUM_0 R(8,${JS_INT},4:0) +set_variable PARAM_NUM_1 R(8,${JS_INT},4:1) +set_variable PARAM_STATUS R(8,4:3,4:200) + +set_variable NUM_TAGS i(3) +set_variable TAGS C(23,chunk_size\000url\000to_file\000) +set_variable VALUES C(16,10\000myurl.html\0000\000) + +set_variable COMPLETE R(24,${JS_STR},4:14,"5555: COMPLETE",2:0) + +###################################################################### + +# These replays are too common to list them separately +# TODO(robertm): make the counts tight, eliminate PPB_Var ASAP + +replay 1 PPB_GetInterface:s:i s("PPB_Messaging;1.0") * i(1) +replay 1 PPB_GetInterface:s:i s("PPB_Core;1.0") * i(1) +replay 1 PPB_GetInterface:s:i s("PPB_Var;1.0") * i(1) +replay 1 PPB_GetInterface:s:i s("PPB_URLRequestInfo;1.0") * i(1) +replay 1 PPB_GetInterface:s:i s("PPB_URLResponseInfo;1.0") * i(1) +replay 1 PPB_GetInterface:s:i s("PPB_URLLoader;1.0") * i(1) + +###################################################################### + +echo +echo "*** INIT MODULE" +# the results contain a process id which is non-determinisitic +rpc PPP_InitializeModule hide-results i(0) ${MODULE} h(pepper_desc) s("${service_string}") * i(0) i(0) + +echo +echo "*** Load URL" +replay 1 PPB_URLRequestInfo_Create:i:i ${INSTANCE} * i(30) +replay 1 PPB_URLLoader_Create:i:i ${INSTANCE} * i(34) +replay 1 PPB_URLRequestInfo_SetProperty:iiC:i i(30) i(0) ${PARAM_STR_URL} * i(1) +replay 1 PPB_URLRequestInfo_SetProperty:iiC:i i(30) i(1) ${PARAM_STR_GET} * i(1) +replay 1 PPB_URLRequestInfo_SetProperty:iiC:i i(30) i(3) ${PARAM_NUM_0} * i(1) +replay 1 PPB_URLLoader_Open:iii:i i(34) i(30) i(1) * i(-1) +replay 1 PPB_Core_ReleaseResource:i: i(30) * +rpc PPP_Instance_DidCreate ${INSTANCE} ${NUM_TAGS} ${TAGS} ${VALUES} * i(0) + +echo +echo "*** async Open Callback" +replay 1 PPB_URLLoader_GetResponseInfo:i:i i(34) * i(38) +replay 1 PPB_URLResponseInfo_GetProperty:ii:C i(38) i(3) * ${PARAM_STATUS} +replay 1 PPB_URLLoader_ReadResponseBody:iii:Ci i(34) i(10) i(2) * C(0,) i(-1) +replay 1 PPB_Core_ReleaseResource:i: i(38) * +rpc RunCompletionCallback i(1) i(0) C(0,) * + +echo +echo "*** async ReaderResponseBody Callback (first 6 bytes)" +replay 1 PPB_URLLoader_ReadResponseBody:iii:Ci i(34) i(10) i(3) * C(0,) i(-1) +rpc RunCompletionCallback i(2) ${FILE_SIZE1} ${FILE_DATA1} * + +echo +echo "*** async ReaderResponseBody Callback (second 6 bytes)" +replay 1 PPB_URLLoader_ReadResponseBody:iii:Ci i(34) i(10) i(4) * C(0,) i(-1) +rpc RunCompletionCallback i(3) ${FILE_SIZE2} ${FILE_DATA2} * + +echo +echo "*** async ReaderResponseBody Callback (eof - 0 bytes)" +replay 1 PPB_Messaging_PostMessage:iC: ${INSTANCE} ${COMPLETE} * +rpc RunCompletionCallback i(4) i(0) C(0,) * + +echo +echo "*** DONE" +rpc PPP_ShutdownModule * diff --git a/ppapi/native_client/tests/ppapi_simple_tests/file1.stdout b/ppapi/native_client/tests/ppapi_simple_tests/file1.stdout new file mode 100644 index 0000000..fff7df5 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_simple_tests/file1.stdout @@ -0,0 +1,133 @@ + +"*** REPLAY PROLOG" + +"*** REGISTER REPLAY METHODS" + +"*** CREATE UPCALL SERVICE" + +"*** INIT MODULE" +rpc call intiated PPP_InitializeModule:iihs:ii +input 0: i(0) +input 1: i(4444) +input 2: h(pepper_desc) +input 3: @LENGTHY_SERVICE_STRING +replaying PPB_GetInterface:s:i: +input 0: s("PPB_Core;1.0") +output 0: i(1) +rpc call complete PPP_InitializeModule:iihs:ii + + +"*** Load URL" +rpc call intiated PPP_Instance_DidCreate:iiCC:i +input 0: i(5555) +input 1: i(3) +input 2: C(23,chunk_size\x00url\x00to_file\x00) +input 3: C(16,10\x00myurl.html\x000\x00) +replaying PPB_GetInterface:s:i: +input 0: s("PPB_URLLoader;1.0") +output 0: i(1) +replaying PPB_URLLoader_Create:i:i: +input 0: i(5555) +output 0: i(34) +replaying PPB_GetInterface:s:i: +input 0: s("PPB_URLRequestInfo;1.0") +output 0: i(1) +replaying PPB_URLRequestInfo_Create:i:i: +input 0: i(5555) +output 0: i(30) +replaying PPB_GetInterface:s:i: +input 0: s("PPB_Var;1.0") +output 0: i(1) +replaying PPB_URLRequestInfo_SetProperty:iiC:i: +input 0: i(30) +input 1: i(0) +input 2: C(24,\x05\x00\x00\x00\n\x00\x00\x00myurl.html\x00\x00\x00\x00\x00\x00) +output 0: i(1) +replaying PPB_URLRequestInfo_SetProperty:iiC:i: +input 0: i(30) +input 1: i(3) +input 2: C(8,\x02\x00\x00\x00\x00\x00\x00\x00) +output 0: i(1) +replaying PPB_URLLoader_Open:iii:i: +input 0: i(34) +input 1: i(30) +input 2: i(1) +output 0: i(-1) +replaying PPB_Core_ReleaseResource:i:: +input 0: i(30) +rpc call complete PPP_Instance_DidCreate:iiCC:i +output 0: i(1) + + +"*** async Open Callback" +rpc call intiated RunCompletionCallback:iiC: +input 0: i(1) +input 1: i(0) +input 2: C(0,) +replaying PPB_URLLoader_GetResponseInfo:i:i: +input 0: i(34) +output 0: i(38) +replaying PPB_GetInterface:s:i: +input 0: s("PPB_URLResponseInfo;1.0") +output 0: i(1) +replaying PPB_URLResponseInfo_GetProperty:ii:C: +input 0: i(38) +input 1: i(3) +output 0: C(8,\x03\x00\x00\x00\xc8\x00\x00\x00) +replaying PPB_URLLoader_ReadResponseBody:iii:Ci: +input 0: i(34) +input 1: i(10) +input 2: i(2) +output 0: C(0,) +output 1: i(-1) +replaying PPB_Core_ReleaseResource:i:: +input 0: i(38) +rpc call complete RunCompletionCallback:iiC: + + +"*** async ReaderResponseBody Callback (first 6 bytes)" +rpc call intiated RunCompletionCallback:iiC: +input 0: i(2) +input 1: i(6) +input 2: C(6,hello ) +replaying PPB_URLLoader_ReadResponseBody:iii:Ci: +input 0: i(34) +input 1: i(10) +input 2: i(3) +output 0: C(0,) +output 1: i(-1) +rpc call complete RunCompletionCallback:iiC: + + +"*** async ReaderResponseBody Callback (second 6 bytes)" +rpc call intiated RunCompletionCallback:iiC: +input 0: i(3) +input 1: i(6) +input 2: C(6,world!) +replaying PPB_URLLoader_ReadResponseBody:iii:Ci: +input 0: i(34) +input 1: i(10) +input 2: i(4) +output 0: C(0,) +output 1: i(-1) +rpc call complete RunCompletionCallback:iiC: + + +"*** async ReaderResponseBody Callback (eof - 0 bytes)" +rpc call intiated RunCompletionCallback:iiC: +input 0: i(4) +input 1: i(0) +input 2: C(0,) +replaying PPB_GetInterface:s:i: +input 0: s("PPB_Messaging;1.0") +output 0: i(1) +replaying PPB_Messaging_PostMessage:iC:: +input 0: i(5555) +input 1: C(24,\x05\x00\x00\x00\x0e\x00\x00\x005555: COMPLETE\x00\x00) +rpc call complete RunCompletionCallback:iiC: + + +"*** DONE" +rpc call intiated PPP_ShutdownModule:: +rpc call complete PPP_ShutdownModule:: + diff --git a/ppapi/native_client/tests/ppapi_simple_tests/file2.stdin b/ppapi/native_client/tests/ppapi_simple_tests/file2.stdin new file mode 100644 index 0000000..c895f36 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_simple_tests/file2.stdin @@ -0,0 +1,79 @@ +# To be used with +# sel_universal_ppapi_replay_prolog.stdin +# define a bunch of variables for readability + +set_variable MODULE i(4444) +set_variable INSTANCE i(5555) + +# Tags used by pepper/srpc to marshall js parameters +set_variable JS_STR 4:5 +set_variable JS_INT 4:2 + +# NOTE: the strings below must not contain unescaped spaces or commas + +set_variable FILE_DATA1 C(6,hello\x20) +set_variable FILE_SIZE1 i(6) +set_variable FILE_DATA2 C(6,world!) +set_variable FILE_SIZE2 i(6) + +set_variable PARAM_STR_URL R(24,${JS_STR},4:10,"myurl.html",6:0) +set_variable PARAM_STR_GET R(16,${JS_STR},4:3,"GET",5:0) +set_variable PARAM_NUM_0 R(8,${JS_INT},4:0) +set_variable PARAM_NUM_1 R(8,${JS_INT},4:1) +set_variable PARAM_STATUS R(8,4:3,4:200) + +set_variable NUM_TAGS i(3) +set_variable TAGS C(23,chunk_size\000url\000to_file\000) +set_variable VALUES C(16,10\000myurl.html\0001\000) + +set_variable ERROR R(48,${JS_STR},4:33,"5555: Error: Finish unexpected rv",7:0) + +###################################################################### + +# These replays are too common to list them separately +# TODO(robertm): make the counts tight, eliminate PPB_Var ASAP + +replay 1 PPB_GetInterface:s:i s("PPB_Messaging;1.0") * i(1) +replay 1 PPB_GetInterface:s:i s("PPB_Core;1.0") * i(1) +replay 1 PPB_GetInterface:s:i s("PPB_Var;1.0") * i(1) +replay 1 PPB_GetInterface:s:i s("PPB_URLRequestInfo;1.0") * i(1) +replay 1 PPB_GetInterface:s:i s("PPB_URLResponseInfo;1.0") * i(1) +replay 1 PPB_GetInterface:s:i s("PPB_URLLoader;1.0") * i(1) +replay 1 PPB_GetInterface:s:i s("PPB_FileIO;1.0") * i(1) + +###################################################################### + +echo +echo "*** INIT MODULE" +# the results contain a process id which is non-determinisitic +rpc PPP_InitializeModule hide-results i(0) ${MODULE} h(pepper_desc) s("${service_string}") * i(0) i(0) + +echo +echo "*** Load URL" +replay 1 PPB_URLRequestInfo_Create:i:i ${INSTANCE} * i(30) +replay 1 PPB_URLLoader_Create:i:i ${INSTANCE} * i(34) +replay 1 PPB_URLRequestInfo_SetProperty:iiC:i i(30) i(0) ${PARAM_STR_URL} * i(1) +replay 1 PPB_URLRequestInfo_SetProperty:iiC:i i(30) i(1) ${PARAM_STR_GET} * i(1) +replay 1 PPB_URLRequestInfo_SetProperty:iiC:i i(30) i(3) ${PARAM_NUM_1} * i(1) +replay 1 PPB_URLLoader_Open:iii:i i(34) i(30) i(1) * i(-1) +replay 1 PPB_Core_ReleaseResource:i: i(30) * +rpc PPP_Instance_DidCreate ${INSTANCE} ${NUM_TAGS} ${TAGS} ${VALUES} * i(0) + +echo +echo "*** async Open Callback" +replay 1 PPB_URLLoader_GetResponseInfo:i:i i(34) * i(38) +replay 1 PPB_URLResponseInfo_GetProperty:ii:C i(38) i(3) * ${PARAM_STATUS} +replay 1 PPB_URLLoader_ReadResponseBody:iii:Ci i(34) i(10) i(2) * C(0,) i(-1) +replay 1 PPB_Core_ReleaseResource:i: i(38) * +replay 1 PPB_Messaging_PostMessage:iC: ${INSTANCE} ${ERROR} * +rpc RunCompletionCallback i(1) i(0) C(0,) * + + +###################################################################### +## EPILOG +###################################################################### +echo +echo "*** DONE" +rpc PPP_ShutdownModule * + + diff --git a/ppapi/native_client/tests/ppapi_simple_tests/file2.stdout b/ppapi/native_client/tests/ppapi_simple_tests/file2.stdout new file mode 100644 index 0000000..79e80bfe --- /dev/null +++ b/ppapi/native_client/tests/ppapi_simple_tests/file2.stdout @@ -0,0 +1,89 @@ + +"*** REPLAY PROLOG" + +"*** REGISTER REPLAY METHODS" + +"*** CREATE UPCALL SERVICE" + +"*** INIT MODULE" +rpc call intiated PPP_InitializeModule:iihs:ii +input 0: i(0) +input 1: i(4444) +input 2: h(pepper_desc) +input 3: @LENGTHY_SERVICE_STRING +replaying PPB_GetInterface:s:i: +input 0: s("PPB_Core;1.0") +output 0: i(1) +rpc call complete PPP_InitializeModule:iihs:ii + + +"*** Load URL" +rpc call intiated PPP_Instance_DidCreate:iiCC:i +input 0: i(5555) +input 1: i(3) +input 2: C(23,chunk_size\x00url\x00to_file\x00) +input 3: C(16,10\x00myurl.html\x001\x00) +replaying PPB_GetInterface:s:i: +input 0: s("PPB_URLLoader;1.0") +output 0: i(1) +replaying PPB_URLLoader_Create:i:i: +input 0: i(5555) +output 0: i(34) +replaying PPB_GetInterface:s:i: +input 0: s("PPB_URLRequestInfo;1.0") +output 0: i(1) +replaying PPB_URLRequestInfo_Create:i:i: +input 0: i(5555) +output 0: i(30) +replaying PPB_GetInterface:s:i: +input 0: s("PPB_Var;1.0") +output 0: i(1) +replaying PPB_URLRequestInfo_SetProperty:iiC:i: +input 0: i(30) +input 1: i(0) +input 2: C(24,\x05\x00\x00\x00\n\x00\x00\x00myurl.html\x00\x00\x00\x00\x00\x00) +output 0: i(1) +replaying PPB_URLRequestInfo_SetProperty:iiC:i: +input 0: i(30) +input 1: i(3) +input 2: C(8,\x02\x00\x00\x00\x01\x00\x00\x00) +output 0: i(1) +replaying PPB_URLLoader_Open:iii:i: +input 0: i(34) +input 1: i(30) +input 2: i(1) +output 0: i(-1) +replaying PPB_Core_ReleaseResource:i:: +input 0: i(30) +rpc call complete PPP_Instance_DidCreate:iiCC:i +output 0: i(1) + + +"*** async Open Callback" +rpc call intiated RunCompletionCallback:iiC: +input 0: i(1) +input 1: i(0) +input 2: C(0,) +replaying PPB_URLLoader_GetResponseInfo:i:i: +input 0: i(34) +output 0: i(38) +replaying PPB_GetInterface:s:i: +input 0: s("PPB_URLResponseInfo;1.0") +output 0: i(1) +replaying PPB_URLResponseInfo_GetProperty:ii:C: +input 0: i(38) +input 1: i(3) +output 0: C(8,\x03\x00\x00\x00\xc8\x00\x00\x00) +replaying PPB_GetInterface:s:i: +input 0: s("PPB_Messaging;1.0") +output 0: i(1) +replaying PPB_Messaging_PostMessage:iC:: +input 0: i(5555) +input 1: C(48,\x05\x00\x00\x00!\x00\x00\x005555: Error: Finish unexpected rv\x00\x00\x00\x00\x00\x00\x00) +rpc call complete RunCompletionCallback:iiC: + + +"*** DONE" +rpc call intiated PPP_ShutdownModule:: +rpc call complete PPP_ShutdownModule:: + diff --git a/ppapi/native_client/tests/ppapi_simple_tests/graphics2d.cc b/ppapi/native_client/tests/ppapi_simple_tests/graphics2d.cc new file mode 100644 index 0000000..875a432 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_simple_tests/graphics2d.cc @@ -0,0 +1,104 @@ +// 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 <stdint.h> + +#include <cmath> +#include <limits> +#include <string> + +#include <nacl/nacl_check.h> +#include <nacl/nacl_log.h> + +#include "ppapi/c/pp_rect.h" +#include "ppapi/c/pp_bool.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/cpp/rect.h" +#include "ppapi/cpp/graphics_2d.h" +#include "ppapi/cpp/image_data.h" +#include "ppapi/cpp/completion_callback.h" +#include "ppapi/cpp/instance.h" +#include "ppapi/cpp/module.h" + +const uint32_t kDefaultColor = 0x2266aa; + +void FillRect(pp::ImageData* image, int left, int top, int width, int height, + uint32_t color) { + for (int y = std::max(0, top); + y < std::min(image->size().height() - 1, top + height); + y++) { + for (int x = std::max(0, left); + x < std::min(image->size().width() - 1, left + width); + x++) + *image->GetAddr32(pp::Point(x, y)) = color; + } +} + +class MyInstance : public pp::Instance { + private: + uint32_t color_; + pp::Size size_; + pp::Graphics2D device_context_; + + void ParseArgs(uint32_t argc, const char* argn[], const char* argv[]) { + for (uint32_t i = 0; i < argc; ++i) { + const std::string tag = argn[i]; + if (tag == "color") color_ = strtol(argv[i], 0, 0); + } + } + + static void FlushCallback(void* thiz, int32_t result) { + // If necessary we can get at the instabce like so: + // MyInstance* instance = static_cast<MyInstance*>(thiz); + } + + public: + explicit MyInstance(PP_Instance instance) + : pp::Instance(instance), color_(kDefaultColor), size_(0, 0) {} + + virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) { + ParseArgs(argc, argn, argv); + return true; + } + + virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip) { + if (position.size().width() == size_.width() && + position.size().height() == size_.height()) { + // No change. We don't care about the position, only the size. + return; + } + + device_context_ = pp::Graphics2D(this, position.size(), false); + CHECK(BindGraphics(device_context_)); + size_ = position.size(); + + pp::ImageData image(this, PP_IMAGEDATAFORMAT_BGRA_PREMUL, size_, true); + CHECK(!image.is_null()); + FillRect(&image, 0, 0, size_.width(), size_.height(), color_); + + device_context_.ReplaceContents(&image); + pp::CompletionCallback cc(FlushCallback, this); + + device_context_.Flush(cc); + } +}; + + +class MyModule : public pp::Module { + public: + // Override CreateInstance to create your customized Instance object. + virtual pp::Instance* CreateInstance(PP_Instance instance) { + return new MyInstance(instance); + } +}; + +namespace pp { + +// Factory function for your specialization of the Module object. +Module* CreateModule() { + return new MyModule(); +} + +} // namespace pp diff --git a/ppapi/native_client/tests/ppapi_simple_tests/graphics2d.stdin b/ppapi/native_client/tests/ppapi_simple_tests/graphics2d.stdin new file mode 100644 index 0000000..f46f225 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_simple_tests/graphics2d.stdin @@ -0,0 +1,63 @@ +# To be used with +# sel_universal_ppapi_replay_prolog.stdin +# define a bunch of variables for readability + +set_variable MODULE i(4444) +set_variable INSTANCE i(5555) +# PP_Size +set_variable IMG_FMT R(8,4:400,4:400) +set_variable IMG_HANDLE i(7) +set_variable GRAPHICS_HANLDE i(8) +# PP_ImageDataDesc +set_variable IMG_FMT2 R(16,4:0,4:400,4:400,4:1600) +# image size is width x height x 4-byte-pixel +set_variable IMG_SIZE 640000 +# PP_Size +set_variable GRAPHICS_FMT R(8,4:400,4:400) + +echo +echo "*** INIT MODULE" +replay 1 PPB_GetInterface:s:i s("PPB_Core;1.0") * i(1) +replay 1 PPB_GetInterface:s:i s("PPB_Instance;1.0") * i(1) +replay 1 PPB_GetInterface:s:i s("PPB_ImageData;1.0") * i(1) +replay 1 PPB_GetInterface:s:i s("PPB_Graphics2D;1.0") * i(1) +# The results contain a process id which is non-determinisitic. The +# 'hide-results' option suppresses this output to help with golden file. +rpc PPP_InitializeModule hide-results i(0) ${MODULE} h(pepper_desc) s("${service_string}") * i(0) i(0) + +echo +echo "*** INIT INSTANCE" +set_variable TAGS C(6,color\000) +set_variable VALUES C(5,0xaa\000) + +# The PPP_GetInterface() call is probably not necessary, we just emulate what +# happens in real life +rpc PPP_GetInterface s("PPP_Instance;1.0") * i(0) +rpc PPP_Instance_DidCreate ${INSTANCE} i(1) ${TAGS} ${VALUES} * i(0) + +echo +echo "*** SETTTING UP VIDEO MEMORY" + +# video size is image size rounded up to 64k +shmem video_handle video_address 655360 +memset ${video_address} 0 ${IMG_SIZE} 0 +checksum ${video_address} 0 ${IMG_SIZE} + +echo +echo "*** TRIGGER REPAINT" +replay 1 PPB_Core_AddRefResource:i: ${GRAPHICS_HANLDE} * +replay 1 PPB_ImageData_Create:iiCi:i ${INSTANCE} i(0) ${IMG_FMT} i(1) * ${IMG_HANDLE} +replay 1 PPB_ImageData_Describe:i:Chii ${IMG_HANDLE} * ${IMG_FMT2} h(video_handle) i(${IMG_SIZE}) i(1) +replay 1 PPB_Graphics2D_Create:iCi:i ${INSTANCE} ${GRAPHICS_FMT} i(0) * ${GRAPHICS_HANLDE} +replay 1 PPB_Instance_BindGraphics:ii:i ${INSTANCE} ${GRAPHICS_HANLDE} * i(1) +replay 1 PPB_Graphics2D_ReplaceContents:ii: ${GRAPHICS_HANLDE} ${IMG_HANDLE} * +replay 1 PPB_Graphics2D_Flush:ii:i ${GRAPHICS_HANLDE} i(1) * i(-1) +replay 1 ReleaseResourceMultipleTimes:ii: ${IMG_HANDLE} i(1) * +replay 1 PPB_Core_ReleaseResource:i: ${GRAPHICS_HANLDE} * +rpc PPP_Instance_DidChangeView ${INSTANCE} I(4,8,79,400,400) I(4,0,0,400,400) * + +echo +echo "*** CHECKING MEMORY" +checksum ${video_address} 0 ${IMG_SIZE} + +rpc PPP_ShutdownModule * diff --git a/ppapi/native_client/tests/ppapi_simple_tests/graphics2d.stdout b/ppapi/native_client/tests/ppapi_simple_tests/graphics2d.stdout new file mode 100644 index 0000000..9c093e7 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_simple_tests/graphics2d.stdout @@ -0,0 +1,90 @@ + +"*** REPLAY PROLOG" + +"*** REGISTER REPLAY METHODS" + +"*** CREATE UPCALL SERVICE" + +"*** INIT MODULE" +rpc call intiated PPP_InitializeModule:iihs:ii +input 0: i(0) +input 1: i(4444) +input 2: h(pepper_desc) +input 3: @LENGTHY_SERVICE_STRING +replaying PPB_GetInterface:s:i: +input 0: s("PPB_Core;1.0") +output 0: i(1) +rpc call complete PPP_InitializeModule:iihs:ii + + +"*** INIT INSTANCE" +rpc call intiated PPP_GetInterface:s:i +input 0: s("PPP_Instance;1.0") +rpc call complete PPP_GetInterface:s:i +output 0: i(1) + +rpc call intiated PPP_Instance_DidCreate:iiCC:i +input 0: i(5555) +input 1: i(1) +input 2: C(6,color\x00) +input 3: C(5,0xaa\x00) +rpc call complete PPP_Instance_DidCreate:iiCC:i +output 0: i(1) + + +"*** SETTTING UP VIDEO MEMORY" +CHECKSUM: 0x00000000 + +"*** TRIGGER REPAINT" +rpc call intiated PPP_Instance_DidChangeView:iII: +input 0: i(5555) +input 1: I(4,8,79,400,400) +input 2: I(4,0,0,400,400) +replaying PPB_GetInterface:s:i: +input 0: s("PPB_Graphics2D;1.0") +output 0: i(1) +replaying PPB_Graphics2D_Create:iCi:i: +input 0: i(5555) +input 1: C(8,\x90\x01\x00\x00\x90\x01\x00\x00) +input 2: i(0) +output 0: i(8) +replaying PPB_GetInterface:s:i: +input 0: s("PPB_Instance;1.0") +output 0: i(1) +replaying PPB_Instance_BindGraphics:ii:i: +input 0: i(5555) +input 1: i(8) +output 0: i(1) +replaying PPB_GetInterface:s:i: +input 0: s("PPB_ImageData;1.0") +output 0: i(1) +replaying PPB_ImageData_Create:iiCi:i: +input 0: i(5555) +input 1: i(0) +input 2: C(8,\x90\x01\x00\x00\x90\x01\x00\x00) +input 3: i(1) +output 0: i(7) +replaying PPB_ImageData_Describe:i:Chii: +input 0: i(7) +output 0: C(16,\x00\x00\x00\x00\x90\x01\x00\x00\x90\x01\x00\x00@\x06\x00\x00) +output 1: h(video_handle) +output 2: i(640000) +output 3: i(1) +replaying PPB_Graphics2D_ReplaceContents:ii:: +input 0: i(8) +input 1: i(7) +replaying ReleaseResourceMultipleTimes:ii:: +input 0: i(7) +input 1: i(1) +replaying PPB_Graphics2D_Flush:ii:i: +input 0: i(8) +input 1: i(1) +output 0: i(-1) +rpc call complete PPP_Instance_DidChangeView:iII: + + +"*** CHECKING MEMORY" +CHECKSUM: 0xe1913cee +rpc call intiated PPP_ShutdownModule:: +rpc call complete PPP_ShutdownModule:: + diff --git a/ppapi/native_client/tests/ppapi_simple_tests/nacl.scons b/ppapi/native_client/tests/ppapi_simple_tests/nacl.scons new file mode 100644 index 0000000..9360505 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_simple_tests/nacl.scons @@ -0,0 +1,71 @@ +# -*- python -*- +# 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. + + +Import('env') + +env.Prepend(CPPDEFINES=['XP_UNIX']) + + +###################################################################### +# REPLAY TESTS +###################################################################### +TESTS = [('audio', ('audio',)), + ('graphics2d',('graphics2d',)), + ('event', ('event',)), + ('file', ('file1', 'file2')), + ] + +for test_exe, test_inputs in TESTS: + nexe = env.ComponentProgram('ppapi_simple_' + test_exe, + [test_exe + '.cc'], + EXTRA_LIBS=['${PPAPI_LIBS}', + 'ppapi_cpp', + 'platform', + 'gio', + 'pthread', + 'm', + ]) + + for test in test_inputs: + node = env.SelUniversalTest( + 'ppapi_simple_' + test + '.out', + nexe, + sel_universal_flags=[ + '--silence_nexe', + '--command_file', + env.File('sel_universal_ppapi_replay_prolog.stdin'), + '--command_file', + env.File(test +'.stdin'), + ], + uses_ppapi=True, + stdout_golden=env.File(test + '.stdout'), + ) + + env.AddNodeToTestSuite(node, + ['small_tests', 'sel_ldr_tests'], + 'run_ppapi_simple_' + test + '_test') + +###################################################################### +# EMULATOR TESTS +###################################################################### +node = env.SelUniversalTest( + 'ppapi_emu_file.out', + env.File('ppapi_simple_file${PROGSUFFIX}'), + sel_universal_flags=[ + '--silence_nexe', + '--command_file', + env.File('ppapi_emu_file.stdin'), + '--url_alias', + 'test.txt', # c.f. ppapi_emu_file.stdin + env.File('test.txt'), + ], + uses_ppapi=True, + stdout_golden=env.File('ppapi_emu_file.stdout'), + ) + +env.AddNodeToTestSuite(node, + ['small_tests', 'sel_ldr_tests'], + 'run_ppapi_emu_file_test') diff --git a/ppapi/native_client/tests/ppapi_simple_tests/ppapi_emu_file.stdin b/ppapi/native_client/tests/ppapi_simple_tests/ppapi_emu_file.stdin new file mode 100644 index 0000000..9b234881 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_simple_tests/ppapi_emu_file.stdin @@ -0,0 +1,52 @@ +# define a bunch of variables for readability + +set_variable MODULE i(4444) +set_variable INSTANCE i(5555) +# NOTE: width and height must match the image_data and +# graphic_2d object requests that the nexe makes +set_variable WIDTH 1000 +set_variable HEIGHT 700 + +echo +echo "*** INITIALIZE PEPPER EMULATION" +# this registers the currently supported PPB_xxx rpcs +pepper_emu_initialize ${INSTANCE} ${WIDTH} ${HEIGHT} demo +echo + +echo +echo "*** CREATE UPCALL SERVICE" +# advertise the registered rpcs to the nexe +install_upcalls service_string pepper_desc +# the variable service string is very long and might change so we suppress it +nondeterministic s("${service_string}") @LENGTHY_SERVICE_STRING + +echo +echo "*** INIT MODULE" +rpc PPP_InitializeModule hide-results i(0) ${MODULE} h(pepper_desc) s("${service_string}") * i(0) i(0) + +echo +echo "*** CHECK INSTANCE CREATION" +# many nexes uses this to trigger instance initialization +set_variable TAGS C(30,url\000to_file\000chunk_size\000pdebug\000) +set_variable VALUES C(18,test.txt\0000\0001024\0001\000) +set_variable NUM_TAGS i(4) +rpc PPP_Instance_DidCreate ${INSTANCE} ${NUM_TAGS} ${TAGS} ${VALUES} * i(0) + +echo +echo "*** TRIGGER REPAINT" +rpc PPP_Instance_DidChangeView ${INSTANCE} I(4,8,79,${WIDTH},${HEIGHT}) I(4,0,0,${WIDTH},${HEIGHT}) * + +# make sure we terminate when seeing the string "5555: COMPLETE" send via +# PostMessage by the nexe when it has fully read the file +echo +echo "REGISTER TERMINATION MESSAGE" +pepper_emu_set_quit_message "5555: COMPLETE" + +echo +echo "*** ENTER EVENT LOOP" +# wait for events and handle them until we see the "quit_message" +pepper_emu_event_loop 0 100000 + +###################################################################### +## EPILOG +###################################################################### diff --git a/ppapi/native_client/tests/ppapi_simple_tests/ppapi_emu_file.stdout b/ppapi/native_client/tests/ppapi_simple_tests/ppapi_emu_file.stdout new file mode 100644 index 0000000..02f84a35 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_simple_tests/ppapi_emu_file.stdout @@ -0,0 +1,41 @@ + +"*** INITIALIZE PEPPER EMULATION" + + +"*** CREATE UPCALL SERVICE" + +"*** INIT MODULE" +rpc call intiated PPP_InitializeModule:iihs:ii +input 0: i(0) +input 1: i(4444) +input 2: h(pepper_desc) +input 3: @LENGTHY_SERVICE_STRING +rpc call complete PPP_InitializeModule:iihs:ii + + +"*** CHECK INSTANCE CREATION" +rpc call intiated PPP_Instance_DidCreate:iiCC:i +input 0: i(5555) +input 1: i(4) +input 2: C(30,url\x00to_file\x00chunk_size\x00pdebug\x00) +input 3: C(18,test.txt\x000\x001024\x001\x00) +rpc call complete PPP_Instance_DidCreate:iiCC:i +output 0: i(1) + + +"*** TRIGGER REPAINT" +rpc call intiated PPP_Instance_DidChangeView:iII: +input 0: i(5555) +input 1: I(4,8,79,1000,700) +input 2: I(4,0,0,1000,700) +rpc call complete PPP_Instance_DidChangeView:iII: + + +"REGISTER TERMINATION MESSAGE" + +"*** ENTER EVENT LOOP" +POST_MESSAGE: [5555: DEBUG: LoadCompleteCallback: 0] +POST_MESSAGE: [5555: DEBUG: ReadCompleteCallback Bytes Read: 1024] +POST_MESSAGE: [5555: DEBUG: ReadCompleteCallback Bytes Read: 980] +POST_MESSAGE: [5555: DEBUG: ReadCompleteCallback Bytes Read: 0] +POST_MESSAGE: [5555: COMPLETE] diff --git a/ppapi/native_client/tests/ppapi_simple_tests/ppapi_geturl_invalid.stdin b/ppapi/native_client/tests/ppapi_simple_tests/ppapi_geturl_invalid.stdin new file mode 100644 index 0000000..4ec8cfe --- /dev/null +++ b/ppapi/native_client/tests/ppapi_simple_tests/ppapi_geturl_invalid.stdin @@ -0,0 +1,87 @@ +# define a bunch of variables for readability + +set_variable MODULE i(4444) +set_variable INSTANCE i(5555) + +# Tags used by pepper/srpc to marshall js parameters +set_variable JS_STR 4:5 +set_variable JS_INT 4:2 + +# NOTE: the strings below must not contain unescaped spaces or commas +set_variable ARG_loadUrl ${JS_STR},4:7,"loadUrl",1:0 +set_variable ARG_ReportResult ${JS_STR},4:12,"ReportResult",4:0 + +set_variable ARG_URL ${JS_STR},4:32,"http://www.google.com/robots.txt" + +set_variable ARG_ERR1 ${JS_STR},4:38,"PPB_URLLoader::Open:\x20PP_ERROR_NOACCESS",2:0 +set_variable ARG_ERR2 ${JS_STR},4:34,"PPB_URLRequestInfo::Create:\x20failed",6:0 +set_variable ARG_GET ${JS_STR},4:3,"GET",5:0 + +set_variable ARG_SUCC ${JS_STR},4:12,"hello\x20world!",4:0 +set_variable ARG_0 ${JS_INT},4:0 +set_variable ARG_1 ${JS_INT},4:1 + +set_variable WINDOW R(24,8:6,8:0x9f,8:0x5f29) +# TODO(robertm) figure out what this represents, maybe PP_Var +set_variable EXCEPTION R(8,8:0) +set_variable NULL R(8,8:0) + +echo +echo "*** INIT MODULE" +replay 99 PPB_GetInterface:s:i s("PPB_Core;1.0") * i(1) +replay 99 PPB_GetInterface:s:i s("PPB_Instance;1.0") * i(1) +replay 99 PPB_GetInterface:s:i s("PPB_Var;1.0") * i(1) +# the results contain a process id which is non-determinisitic +rpc PPP_InitializeModule hide-results i(0) ${MODULE} h(pepper_desc) s("${service_string}") * i(0) i(0) + +echo +echo "*** TRIGGER REPAINT" +rpc PPP_Instance_DidChangeView ${INSTANCE} I(4,8,79,400,400) I(4,0,0,400,400) * +# leave time for flush of stdout + +###################################################################### +## URL +###################################################################### +echo +echo "*** CALL loadUrl(): url2 as buffer - expected to fail" +replay 1 PPB_GetInterface:s:i s("PPB_URLRequestInfo;1.0") * i(1) +replay 1 PPB_GetInterface:s:i s("PPB_URLResponseInfo;1.0") * i(1) +replay 1 PPB_GetInterface:s:i s("PPB_URLLoader;1.0") * i(1) +replay 1 PPB_GetInterface:s:i s("PPB_FileIO;1.0") * i(1) + +replay 1 PPB_FileIO_Create:i:i ${INSTANCE} * i(35) +replay 1 PPB_URLRequestInfo_Create:i:i ${INSTANCE} * i(40) +replay 1 PPB_URLLoader_Create:i:i ${INSTANCE} * i(44) + +replay 1 PPB_FileIO_IsFileIO:i:i i(35) * i(1) +replay 1 PPB_URLRequestInfo_IsURLRequestInfo:i:i i(35) * i(0) +replay 1 PPB_URLResponseInfo_IsURLResponseInfo:i:i i(35) * i(0) +replay 1 PPB_URLLoader_IsURLLoader:i:i i(35) * i(0) + +replay 1 PPB_FileIO_IsFileIO:i:i i(40) * i(0) +replay 1 PPB_URLRequestInfo_IsURLRequestInfo:i:i i(40) * i(1) +replay 1 PPB_URLResponseInfo_IsURLResponseInfo:i:i i(40) * i(0) +replay 1 PPB_URLLoader_IsURLLoader:i:i i(40) * i(0) + +replay 1 PPB_FileIO_IsFileIO:i:i i(44) * i(0) +replay 1 PPB_URLRequestInfo_IsURLRequestInfo:i:i i(44) * i(0) +replay 1 PPB_URLResponseInfo_IsURLResponseInfo:i:i i(44) * i(0) +replay 1 PPB_URLLoader_IsURLLoader:i:i i(44) * i(1) + +replay 1 PPB_URLRequestInfo_SetProperty:iiC:i i(40) i(0) R(40,${ARG_URL}) * i(1) +replay 1 PPB_URLRequestInfo_SetProperty:iiC:i i(40) i(1) R(16,${ARG_GET}) * i(1) +replay 1 PPB_URLRequestInfo_SetProperty:iiC:i i(40) i(3) R(8,${ARG_0}) * i(1) + +replay 1 PPB_URLLoader_Open:iii:i i(44) i(40) i(1) * i(-7) + +replay 1 PPB_Core_ReleaseResource:i: i(35) * +replay 1 PPB_Core_ReleaseResource:i: i(40) * +replay 1 PPB_Core_ReleaseResource:i: i(44) * +rpc Call ${OBJECT} R(16,${ARG_loadUrl}) i(2) R(48,${ARG_URL},${ARG_0}) ${NULL} * C(8) C(8) + +###################################################################### +## EPILOG +###################################################################### +echo +echo "*** DONE" +rpc PPP_ShutdownModule * diff --git a/ppapi/native_client/tests/ppapi_simple_tests/ppapi_geturl_invalid.stdout b/ppapi/native_client/tests/ppapi_simple_tests/ppapi_geturl_invalid.stdout new file mode 100644 index 0000000..3dc8641 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_simple_tests/ppapi_geturl_invalid.stdout @@ -0,0 +1,135 @@ + +"*** REPLAY PROLOG" + +"*** REGISTER REPLAY METHODS" + +"*** INITIALIZE PEPPER" + +"*** CREATE UPCALL SERVICE" + +"*** INIT MODULE" +rpc call intiated PPP_InitializeModule:iihs:ii +input 0: i(0) +input 1: i(4444) +input 2: h(pepper_desc) +input 3: @LENGTHY_SERIVE_STRING +replaying PPB_GetInterface:s:i: +input 0: s("PPB_Core;1.0") +output 0: i(1) +replaying PPB_GetInterface:s:i: +input 0: s("PPB_Instance;1.0") +output 0: i(1) +replaying PPB_GetInterface:s:i: +input 0: s("PPB_Var;1.0") +output 0: i(1) +rpc call complete PPP_InitializeModule:iihs:ii + + +"*** TRIGGER REPAINT" +rpc call intiated PPP_Instance_DidChangeView:iII: +input 0: i(5555) +input 1: I(4,8,79,400,400) +input 2: I(4,0,0,400,400) +rpc call complete PPP_Instance_DidChangeView:iII: + + + +"*** CALL loadUrl(): url2 as buffer - expected to fail" +rpc call intiated Call:CCiCC:CC +input 0: @THE_OBJECT +input 1: C(16,\x05\x00\x00\x00\x07\x00\x00\x00loadUrl\x00) +input 2: i(2) +input 3: C(48,\x05\x00\x00\x00 \x00\x00\x00http://www.google.com/robots.txt\x02\x00\x00\x00\x00\x00\x00\x00) +input 4: C(8,\x00\x00\x00\x00\x00\x00\x00\x00) +replaying PPB_GetInterface:s:i: +input 0: s("PPB_URLRequestInfo;1.0") +output 0: i(1) +replaying PPB_URLRequestInfo_Create:i:i: +input 0: i(5555) +output 0: i(40) +replaying PPB_GetInterface:s:i: +input 0: s("PPB_URLResponseInfo;1.0") +output 0: i(1) +replaying PPB_GetInterface:s:i: +input 0: s("PPB_URLLoader;1.0") +output 0: i(1) +replaying PPB_URLLoader_Create:i:i: +input 0: i(5555) +output 0: i(44) +replaying PPB_GetInterface:s:i: +input 0: s("PPB_FileIO;1.0") +output 0: i(1) +replaying PPB_FileIO_Create:i:i: +input 0: i(5555) +output 0: i(35) +replaying PPB_FileIO_IsFileIO:i:i: +input 0: i(40) +output 0: i(0) +replaying PPB_URLRequestInfo_IsURLRequestInfo:i:i: +input 0: i(40) +output 0: i(1) +replaying PPB_URLResponseInfo_IsURLResponseInfo:i:i: +input 0: i(40) +output 0: i(0) +replaying PPB_URLLoader_IsURLLoader:i:i: +input 0: i(40) +output 0: i(0) +replaying PPB_FileIO_IsFileIO:i:i: +input 0: i(44) +output 0: i(0) +replaying PPB_URLRequestInfo_IsURLRequestInfo:i:i: +input 0: i(44) +output 0: i(0) +replaying PPB_URLResponseInfo_IsURLResponseInfo:i:i: +input 0: i(44) +output 0: i(0) +replaying PPB_URLLoader_IsURLLoader:i:i: +input 0: i(44) +output 0: i(1) +replaying PPB_FileIO_IsFileIO:i:i: +input 0: i(35) +output 0: i(1) +replaying PPB_URLRequestInfo_IsURLRequestInfo:i:i: +input 0: i(35) +output 0: i(0) +replaying PPB_URLResponseInfo_IsURLResponseInfo:i:i: +input 0: i(35) +output 0: i(0) +replaying PPB_URLLoader_IsURLLoader:i:i: +input 0: i(35) +output 0: i(0) +replaying PPB_URLRequestInfo_SetProperty:iiC:i: +input 0: i(40) +input 1: i(0) +input 2: C(40,\x05\x00\x00\x00 \x00\x00\x00http://www.google.com/robots.txt) +output 0: i(1) +replaying PPB_URLRequestInfo_SetProperty:iiC:i: +input 0: i(40) +input 1: i(1) +input 2: C(16,\x05\x00\x00\x00\x03\x00\x00\x00GET\x00\x00\x00\x00\x00) +output 0: i(1) +replaying PPB_URLRequestInfo_SetProperty:iiC:i: +input 0: i(40) +input 1: i(3) +input 2: C(8,\x02\x00\x00\x00\x00\x00\x00\x00) +output 0: i(1) +replaying PPB_URLLoader_Open:iii:i: +input 0: i(44) +input 1: i(40) +input 2: i(1) +output 0: i(-7) +replaying PPB_Core_ReleaseResource:i:: +input 0: i(40) +replaying PPB_Core_ReleaseResource:i:: +input 0: i(44) +replaying PPB_Core_ReleaseResource:i:: +input 0: i(35) +rpc call complete Call:CCiCC:CC +output 0: C(8,\x00\x00\x00\x00\x00\x00\x00\x00) +output 1: C(8,\x00\x00\x00\x00\x00\x00\x00\x00) + + +"*** DONE" +rpc call intiated PPP_ShutdownModule:: +rpc call complete PPP_ShutdownModule:: + diff --git a/ppapi/native_client/tests/ppapi_simple_tests/ppapi_geturl_valid.stdin b/ppapi/native_client/tests/ppapi_simple_tests/ppapi_geturl_valid.stdin new file mode 100644 index 0000000..d4696b2 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_simple_tests/ppapi_geturl_valid.stdin @@ -0,0 +1,151 @@ +# define a bunch of variables for readability + +set_variable MODULE i(4444) +set_variable INSTANCE i(5555) + +# Tags used by pepper/srpc to marshall js parameters +set_variable JS_STR 4:5 +set_variable JS_INT 4:2 + +# NOTE: the strings below must not contain unescaped spaces or commas +set_variable ARG_loadUrl ${JS_STR},4:7,"loadUrl",1:0 +set_variable ARG_ReportResult ${JS_STR},4:12,"ReportResult",4:0 + +set_variable ARG_URL ${JS_STR},4:25,"ppapi_geturl_success.html",7:0 +set_variable ARG_URL_FULL ${JS_STR},4:47,"http://localhost:5103/ppapi_geturl_success.html",1:0 + +set_variable ARG_GET ${JS_STR},4:3,"GET",5:0 + +set_variable ARG_SUCC ${JS_STR},4:12,"hello\x20world!",4:0 +set_variable ARG_0 ${JS_INT},4:0 +set_variable ARG_1 ${JS_INT},4:1 + +set_variable WINDOW R(24,8:6,8:0x9f,8:0x5f29) +# TODO(robertm) figure out what this represents, maybe PP_Var +set_variable EXCEPTION R(8,8:0) +set_variable NULL R(8,8:0) + +echo +echo "*** INIT MODULE" +replay 99 PPB_GetInterface:s:i s("PPB_Core;1.0") * i(1) +replay 99 PPB_GetInterface:s:i s("PPB_Instance;1.0") * i(1) +replay 99 PPB_GetInterface:s:i s("PPB_Var;1.0") * i(1) +# the results contain a process id which is non-determinisitic +rpc PPP_InitializeModule hide-results i(0) ${MODULE} h(pepper_desc) s("${service_string}") * i(0) i(0) + +echo +echo "*** TRIGGER REPAINT" +rpc PPP_Instance_DidChangeView ${INSTANCE} I(4,8,79,400,400) I(4,0,0,400,400) * +# leave time for flush of stdout + +echo +echo "*** GET INSTANCE OBJECT" +rpc PPP_Instance_GetInstanceObject hide-results ${INSTANCE} * C(16) +# save result to variable and also register it as non-deterministic +set_variable OBJECT ${result0} +nondeterministic ${result0} @THE_OBJECT + +###################################################################### +## URL (buffer) +###################################################################### + +echo +echo "*** CALL loadUrl(): as buffer" +replay 1 PPB_GetInterface:s:i s("PPB_URLRequestInfo;1.0") * i(1) +replay 1 PPB_GetInterface:s:i s("PPB_URLResponseInfo;1.0") * i(1) +replay 1 PPB_GetInterface:s:i s("PPB_URLLoader;1.0") * i(1) +replay 1 PPB_GetInterface:s:i s("PPB_FileIO;1.0") * i(1) + +replay 1 PPB_FileIO_Create:i:i ${INSTANCE} * i(35) +replay 1 PPB_URLRequestInfo_Create:i:i ${INSTANCE} * i(30) +replay 1 PPB_URLLoader_Create:i:i ${INSTANCE} * i(34) + +replay 1 PPB_FileIO_IsFileIO:i:i i(35) * i(1) +replay 1 PPB_URLRequestInfo_IsURLRequestInfo:i:i i(35) * i(0) +replay 1 PPB_URLResponseInfo_IsURLResponseInfo:i:i i(35) * i(0) +replay 1 PPB_URLLoader_IsURLLoader:i:i i(35) * i(0) + +replay 1 PPB_URLRequestInfo_IsURLRequestInfo:i:i i(30) * i(1) +replay 1 PPB_URLResponseInfo_IsURLResponseInfo:i:i i(30) * i(0) +replay 1 PPB_URLLoader_IsURLLoader:i:i i(30) * i(0) +replay 1 PPB_FileIO_IsFileIO:i:i i(30) * i(0) + +replay 1 PPB_URLRequestInfo_IsURLRequestInfo:i:i i(34) * i(0) +replay 1 PPB_URLResponseInfo_IsURLResponseInfo:i:i i(34) * i(0) +replay 1 PPB_URLLoader_IsURLLoader:i:i i(34) * i(1) +replay 1 PPB_FileIO_IsFileIO:i:i i(34) * i(0) + +replay 1 PPB_URLRequestInfo_SetProperty:iiC:i i(30) i(0) R(40,${ARG_URL}) * i(1) +replay 1 PPB_URLRequestInfo_SetProperty:iiC:i i(30) i(1) R(16,${ARG_GET}) * i(1) +replay 1 PPB_URLRequestInfo_SetProperty:iiC:i i(30) i(3) R(8,${ARG_0}) * i(1) + +replay 1 PPB_URLLoader_Open:iii:i i(34) i(30) i(1) * i(-1) +rpc Call ${OBJECT} R(16,${ARG_loadUrl}) i(2) R(48,${ARG_URL},${ARG_0}) ${NULL} * C(8) C(8) + +echo +echo "*** async response part1" +replay 1 PPB_URLLoader_GetResponseInfo:i:i i(34) * i(38) +replay 1 PPB_FileIO_IsFileIO:i:i i(38) * i(0) +replay 1 PPB_URLRequestInfo_IsURLRequestInfo:i:i i(38) * i(0) +replay 1 PPB_URLResponseInfo_IsURLResponseInfo:i:i i(38) * i(1) +replay 1 PPB_URLLoader_IsURLLoader:i:i i(38) * i(0) +replay 1 PPB_URLResponseInfo_GetProperty:ii:C i(38) i(0) * R(56,${ARG_URL_FULL}) +replay 1 PPB_URLResponseInfo_GetProperty:ii:C i(38) i(3) * R(8,4:3,4:200) +replay 1 PPB_URLLoader_ReadResponseBody:iii:Ci i(34) i(1024) i(2) * C(0,) i(-1) +rpc RunCompletionCallback i(1) i(0) C(0,) * + +echo +echo "*** async response part2" +replay 1 PPB_URLLoader_ReadResponseBody:iii:Ci i(34) i(1024) i(3) * C(0,) i(-1) +rpc RunCompletionCallback i(2) i(12) C(12,hello\x20world!) * + +###################################################################### +## URL (file) +###################################################################### + +echo +echo "*** CALL loadUrl(): as file" +replay 1 PPB_GetInterface:s:i s("PPB_FileIO;1.0") * i(1) +replay 1 PPB_GetInterface:s:i s("PPB_URLRequestInfo;1.0") * i(1) +replay 1 PPB_GetInterface:s:i s("PPB_URLResponseInfo;1.0") * i(1) +replay 1 PPB_GetInterface:s:i s("PPB_URLLoader;1.0") * i(1) + +replay 1 PPB_URLLoader_Create:i:i ${INSTANCE} * i(34) +replay 1 PPB_URLRequestInfo_Create:i:i ${INSTANCE} * i(30) +replay 1 PPB_FileIO_Create:i:i ${INSTANCE} * i(66) + +replay 1 PPB_FileIO_IsFileIO:i:i i(66) * i(1) +replay 1 PPB_URLLoader_IsURLLoader:i:i i(66) * i(0) +replay 1 PPB_URLResponseInfo_IsURLResponseInfo:i:i i(66) * i(0) +replay 1 PPB_URLRequestInfo_IsURLRequestInfo:i:i i(66) * i(0) + +replay 1 PPB_FileIO_IsFileIO:i:i i(30) * i(0) +replay 1 PPB_URLResponseInfo_IsURLResponseInfo:i:i i(30) * i(0) +replay 1 PPB_URLRequestInfo_IsURLRequestInfo:i:i i(30) * i(1) +replay 1 PPB_URLLoader_IsURLLoader:i:i i(30) * i(0) + +replay 1 PPB_FileIO_IsFileIO:i:i i(34) * i(0) +replay 1 PPB_URLRequestInfo_IsURLRequestInfo:i:i i(34) * i(0) +replay 1 PPB_URLResponseInfo_IsURLResponseInfo:i:i i(34) * i(0) +replay 1 PPB_URLLoader_IsURLLoader:i:i i(34) * i(1) + +replay 1 PPB_URLRequestInfo_SetProperty:iiC:i i(30) i(0) R(40,${ARG_URL}) * i(1) +replay 1 PPB_URLRequestInfo_SetProperty:iiC:i i(30) i(1) R(16,${ARG_GET}) * i(1) +replay 1 PPB_URLRequestInfo_SetProperty:iiC:i i(30) i(3) R(8,${ARG_1}) * i(1) + +replay 1 PPB_URLLoader_Open:iii:i i(34) i(30) i(4) * i(-1) + +replay 1 PPB_Core_ReleaseResource:i: i(30) * +replay 1 PPB_Core_ReleaseResource:i: i(34) * +replay 1 PPB_Core_ReleaseResource:i: i(66) * + +replay 1 Call:CCiCC:CC R(16,8:0x9f,8:0x5f29) R(24,${ARG_ReportResult}) i(4) R(80,${ARG_URL},${ARG_1},${ARG_SUCC},${ARG_1}) ${NULL} * ${NULL} ${NULL} + +rpc Call ${OBJECT} R(16,${ARG_loadUrl}) i(2) R(48,${ARG_URL},${ARG_1}) ${NULL} * C(8) C(8) + +###################################################################### +## EPILOG +###################################################################### +echo +echo "*** DONE" +rpc PPP_ShutdownModule * diff --git a/ppapi/native_client/tests/ppapi_simple_tests/ppapi_geturl_valid.stdout b/ppapi/native_client/tests/ppapi_simple_tests/ppapi_geturl_valid.stdout new file mode 100644 index 0000000..16ce922 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_simple_tests/ppapi_geturl_valid.stdout @@ -0,0 +1,272 @@ + +"*** REPLAY PROLOG" + +"*** REGISTER REPLAY METHODS" + +"*** INITIALIZE PEPPER" + +"*** CREATE UPCALL SERVICE" + +"*** INIT MODULE" +rpc call intiated PPP_InitializeModule:iihs:ii +input 0: i(0) +input 1: i(4444) +input 2: h(pepper_desc) +input 3: @LENGTHY_SERIVE_STRING +replaying PPB_GetInterface:s:i: +input 0: s("PPB_Core;1.0") +output 0: i(1) +replaying PPB_GetInterface:s:i: +input 0: s("PPB_Instance;1.0") +output 0: i(1) +replaying PPB_GetInterface:s:i: +input 0: s("PPB_Var;1.0") +output 0: i(1) +rpc call complete PPP_InitializeModule:iihs:ii + + +"*** TRIGGER REPAINT" +rpc call intiated PPP_Instance_DidChangeView:iII: +input 0: i(5555) +input 1: I(4,8,79,400,400) +input 2: I(4,0,0,400,400) +rpc call complete PPP_Instance_DidChangeView:iII: + + +"*** CALL loadUrl(): as buffer" +rpc call intiated Call:CCiCC:CC +input 0: @THE_OBJECT +input 1: C(16,\x05\x00\x00\x00\x07\x00\x00\x00loadUrl\x00) +input 2: i(2) +input 3: C(48,\x05\x00\x00\x00\x19\x00\x00\x00ppapi_geturl_success.html\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00) +input 4: C(8,\x00\x00\x00\x00\x00\x00\x00\x00) +replaying PPB_GetInterface:s:i: +input 0: s("PPB_URLRequestInfo;1.0") +output 0: i(1) +replaying PPB_URLRequestInfo_Create:i:i: +input 0: i(5555) +output 0: i(30) +replaying PPB_GetInterface:s:i: +input 0: s("PPB_URLResponseInfo;1.0") +output 0: i(1) +replaying PPB_GetInterface:s:i: +input 0: s("PPB_URLLoader;1.0") +output 0: i(1) +replaying PPB_URLLoader_Create:i:i: +input 0: i(5555) +output 0: i(34) +replaying PPB_GetInterface:s:i: +input 0: s("PPB_FileIO;1.0") +output 0: i(1) +replaying PPB_FileIO_Create:i:i: +input 0: i(5555) +output 0: i(35) +replaying PPB_FileIO_IsFileIO:i:i: +input 0: i(30) +output 0: i(0) +replaying PPB_URLRequestInfo_IsURLRequestInfo:i:i: +input 0: i(30) +output 0: i(1) +replaying PPB_URLResponseInfo_IsURLResponseInfo:i:i: +input 0: i(30) +output 0: i(0) +replaying PPB_URLLoader_IsURLLoader:i:i: +input 0: i(30) +output 0: i(0) +replaying PPB_FileIO_IsFileIO:i:i: +input 0: i(34) +output 0: i(0) +replaying PPB_URLRequestInfo_IsURLRequestInfo:i:i: +input 0: i(34) +output 0: i(0) +replaying PPB_URLResponseInfo_IsURLResponseInfo:i:i: +input 0: i(34) +output 0: i(0) +replaying PPB_URLLoader_IsURLLoader:i:i: +input 0: i(34) +output 0: i(1) +replaying PPB_FileIO_IsFileIO:i:i: +input 0: i(35) +output 0: i(1) +replaying PPB_URLRequestInfo_IsURLRequestInfo:i:i: +input 0: i(35) +output 0: i(0) +replaying PPB_URLResponseInfo_IsURLResponseInfo:i:i: +input 0: i(35) +output 0: i(0) +replaying PPB_URLLoader_IsURLLoader:i:i: +input 0: i(35) +output 0: i(0) +replaying PPB_URLRequestInfo_SetProperty:iiC:i: +input 0: i(30) +input 1: i(0) +input 2: C(40,\x05\x00\x00\x00\x19\x00\x00\x00ppapi_geturl_success.html\x00\x00\x00\x00\x00\x00\x00) +output 0: i(1) +replaying PPB_URLRequestInfo_SetProperty:iiC:i: +input 0: i(30) +input 1: i(1) +input 2: C(16,\x05\x00\x00\x00\x03\x00\x00\x00GET\x00\x00\x00\x00\x00) +output 0: i(1) +replaying PPB_URLRequestInfo_SetProperty:iiC:i: +input 0: i(30) +input 1: i(3) +input 2: C(8,\x02\x00\x00\x00\x00\x00\x00\x00) +output 0: i(1) +replaying PPB_URLLoader_Open:iii:i: +input 0: i(34) +input 1: i(30) +input 2: i(1) +output 0: i(-1) +rpc call complete Call:CCiCC:CC +output 0: C(8,\x00\x00\x00\x00\x00\x00\x00\x00) +output 1: C(8,\x00\x00\x00\x00\x00\x00\x00\x00) + + +"*** async response part1" +rpc call intiated RunCompletionCallback:iiC: +input 0: i(1) +input 1: i(0) +input 2: C(0,) +replaying PPB_URLLoader_GetResponseInfo:i:i: +input 0: i(34) +output 0: i(38) +replaying PPB_FileIO_IsFileIO:i:i: +input 0: i(38) +output 0: i(0) +replaying PPB_URLRequestInfo_IsURLRequestInfo:i:i: +input 0: i(38) +output 0: i(0) +replaying PPB_URLResponseInfo_IsURLResponseInfo:i:i: +input 0: i(38) +output 0: i(1) +replaying PPB_URLLoader_IsURLLoader:i:i: +input 0: i(38) +output 0: i(0) +replaying PPB_URLResponseInfo_GetProperty:ii:C: +input 0: i(38) +input 1: i(0) +output 0: C(56,\x05\x00\x00\x00/\x00\x00\x00http://localhost:5103/ppapi_geturl_success.html\x00) +replaying PPB_URLResponseInfo_GetProperty:ii:C: +input 0: i(38) +input 1: i(3) +output 0: C(8,\x03\x00\x00\x00\xc8\x00\x00\x00) +replaying PPB_URLLoader_ReadResponseBody:iii:Ci: +input 0: i(34) +input 1: i(1024) +input 2: i(2) +output 0: C(0,) +output 1: i(-1) +rpc call complete RunCompletionCallback:iiC: + + +"*** async response part2" +rpc call intiated RunCompletionCallback:iiC: +input 0: i(2) +input 1: i(12) +input 2: C(12,hello world!) +replaying PPB_URLLoader_ReadResponseBody:iii:Ci: +input 0: i(34) +input 1: i(1024) +input 2: i(3) +output 0: C(0,) +output 1: i(-1) +rpc call complete RunCompletionCallback:iiC: + + +"*** async response eof - report success" +rpc call intiated RunCompletionCallback:iiC: +input 0: i(3) +input 1: i(0) +input 2: C(0,) +replaying PPB_Core_ReleaseResource:i:: +input 0: i(30) +replaying PPB_Core_ReleaseResource:i:: +input 0: i(34) +replaying PPB_Core_ReleaseResource:i:: +input 0: i(38) +replaying PPB_Core_ReleaseResource:i:: +input 0: i(35) +rpc call complete RunCompletionCallback:iiC: + + +"*** CALL loadUrl(): as file" +rpc call intiated Call:CCiCC:CC +input 0: @THE_OBJECT +input 1: C(16,\x05\x00\x00\x00\x07\x00\x00\x00loadUrl\x00) +input 2: i(2) +input 3: C(48,\x05\x00\x00\x00\x19\x00\x00\x00ppapi_geturl_success.html\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00) +input 4: C(8,\x00\x00\x00\x00\x00\x00\x00\x00) +replaying PPB_URLRequestInfo_Create:i:i: +input 0: i(5555) +output 0: i(30) +replaying PPB_URLLoader_Create:i:i: +input 0: i(5555) +output 0: i(34) +replaying PPB_FileIO_Create:i:i: +input 0: i(5555) +output 0: i(66) +replaying PPB_FileIO_IsFileIO:i:i: +input 0: i(30) +output 0: i(0) +replaying PPB_URLRequestInfo_IsURLRequestInfo:i:i: +input 0: i(30) +output 0: i(1) +replaying PPB_URLResponseInfo_IsURLResponseInfo:i:i: +input 0: i(30) +output 0: i(0) +replaying PPB_URLLoader_IsURLLoader:i:i: +input 0: i(30) +output 0: i(0) +replaying PPB_FileIO_IsFileIO:i:i: +input 0: i(34) +output 0: i(0) +replaying PPB_URLRequestInfo_IsURLRequestInfo:i:i: +input 0: i(34) +output 0: i(0) +replaying PPB_URLResponseInfo_IsURLResponseInfo:i:i: +input 0: i(34) +output 0: i(0) +replaying PPB_URLLoader_IsURLLoader:i:i: +input 0: i(34) +output 0: i(1) +replaying PPB_FileIO_IsFileIO:i:i: +input 0: i(66) +output 0: i(1) +replaying PPB_URLRequestInfo_IsURLRequestInfo:i:i: +input 0: i(66) +output 0: i(0) +replaying PPB_URLResponseInfo_IsURLResponseInfo:i:i: +input 0: i(66) +output 0: i(0) +replaying PPB_URLLoader_IsURLLoader:i:i: +input 0: i(66) +output 0: i(0) +replaying PPB_URLRequestInfo_SetProperty:iiC:i: +input 0: i(30) +input 1: i(0) +input 2: C(40,\x05\x00\x00\x00\x19\x00\x00\x00ppapi_geturl_success.html\x00\x00\x00\x00\x00\x00\x00) +output 0: i(1) +replaying PPB_URLRequestInfo_SetProperty:iiC:i: +input 0: i(30) +input 1: i(1) +input 2: C(16,\x05\x00\x00\x00\x03\x00\x00\x00GET\x00\x00\x00\x00\x00) +output 0: i(1) +replaying PPB_URLRequestInfo_SetProperty:iiC:i: +input 0: i(30) +input 1: i(3) +input 2: C(8,\x02\x00\x00\x00\x01\x00\x00\x00) +output 0: i(1) +replaying PPB_URLLoader_Open:iii:i: +input 0: i(34) +input 1: i(30) +input 2: i(4) +output 0: i(-1) +rpc call complete Call:CCiCC:CC +output 0: C(8,\x00\x00\x00\x00\x00\x00\x00\x00) +output 1: C(8,\x00\x00\x00\x00\x00\x00\x00\x00) + + +"*** DONE" +rpc call intiated PPP_ShutdownModule:: +rpc call complete PPP_ShutdownModule:: + diff --git a/ppapi/native_client/tests/ppapi_simple_tests/sel_universal_ppapi_replay_prolog.stdin b/ppapi/native_client/tests/ppapi_simple_tests/sel_universal_ppapi_replay_prolog.stdin new file mode 100644 index 0000000..3622ab4 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_simple_tests/sel_universal_ppapi_replay_prolog.stdin @@ -0,0 +1,104 @@ +# First register a bunch of dummy replays with zero count +# so that those signatures will get registered during "install_upcalls" +# Note: because of the zero count we do not have to get the parameters right +# +# Enumerating all known methods ahead of time helps in many ways: +# * we can delay registering non zero count replays till later which help +# readability +# * we get an error if for some reason the nexe calls one of these functions. +# Sadly, the nexe usually fails silently when a method is missing from a +# service +# +# This must be updated by hand when signatures change. + +echo +echo "*** REPLAY PROLOG" + +replay 0 HasProperty:CCC:iC * +replay 0 HasMethod:CCC:iC * +replay 0 GetProperty:CCC:CC * +replay 0 GetAllPropertyNames:CC:iCC * +replay 0 SetProperty:CCCC:C * +replay 0 RemoveProperty:CCC:C * +replay 0 Call:CCiCC:CC * +replay 0 Construct:CiCC:CC * +replay 0 Deallocate:C: * +replay 0 PPB_GetInterface:s:i * + +replay 0 PPB_Audio_Create:ii:i * +replay 0 PPB_Audio_IsAudio:i:i * +replay 0 PPB_Audio_GetCurrentConfig:i:i * +replay 0 PPB_Audio_StopPlayback:i:i * +replay 0 PPB_Audio_StartPlayback:i:i * + +replay 0 PPB_AudioConfig_CreateStereo16Bit:iii:i * +replay 0 PPB_AudioConfig_IsAudioConfig:i:i * +replay 0 PPB_AudioConfig_RecommendSampleFrameCount:ii:i * +replay 0 PPB_AudioConfig_GetSampleRate:i:i * +replay 0 PPB_AudioConfig_GetSampleFrameCount:i:i * + +replay 0 PPB_Core_AddRefResource:i: * +replay 0 PPB_Core_ReleaseResource:i: * +replay 0 PPB_Core_GetTime::d * +replay 0 PPB_Core_CallOnMainThread:iii: * + +replay 0 ReleaseResourceMultipleTimes:ii: * + +replay 0 PPB_FileIO_Create:i:i * +replay 0 PPB_FileIO_IsFileIO:i:i * +replay 0 PPB_FileIO_Open:iiii:i * +replay 0 PPB_FileIO_Read:ilii:Ci * + +replay 0 PPB_Graphics2D_Create:iCi:i * +replay 0 PPB_Graphics2D_IsGraphics2D:i:i * +replay 0 PPB_Graphics2D_Describe:i:Cii * +replay 0 PPB_Graphics2D_PaintImageData:iiCC: * +replay 0 PPB_Graphics2D_Scroll:iCC: * +replay 0 PPB_Graphics2D_ReplaceContents:ii: * +replay 0 PPB_Graphics2D_Flush:ii:i * + +replay 0 PPB_ImageData_GetNativeImageDataFormat::i * +replay 0 PPB_ImageData_IsImageDataFormatSupported:i:i * +replay 0 PPB_ImageData_Create:iiCi:i * +replay 0 PPB_ImageData_IsImageData:i:i * +replay 0 PPB_ImageData_Describe:i:Chii * + +replay 0 PPB_Instance_BindGraphics:ii:i * +replay 0 PPB_Instance_IsFullFrame:i:i * + +replay 0 PPB_URLRequestInfo_Create:i:i * +replay 0 PPB_URLRequestInfo_IsURLRequestInfo:i:i * +replay 0 PPB_URLRequestInfo_IsURLResponseInfo:i:i * +replay 0 PPB_URLRequestInfo_SetProperty:iiC:i * +replay 0 PPB_URLRequestInfo_AppendDataToBody:iC:i * +replay 0 PPB_URLRequestInfo_AppendFileToBody:illld:i * + +replay 0 PPB_URLLoader_Open:iii:i * +replay 0 PPB_URLLoader_Create:i:i * +replay 0 PPB_URLLoader_FollowRedirect:ii:i * +replay 0 PPB_URLLoader_GetUploadProgress:i:lli * +replay 0 PPB_URLLoader_GetDownloadProgress:i:lli * +replay 0 PPB_URLLoader_ReadResponseBody:iii:Ci * +replay 0 PPB_URLLoader_GetResponseInfo:i:i * +replay 0 PPB_URLLoader_Close:i: * +replay 0 PPB_URLLoader_IsURLLoader:i:i * + +replay 0 PPB_URLResponseInfo_IsURLResponseInfo:i:i * +replay 0 PPB_URLResponseInfo_GetProperty:ii:C * +replay 0 PPB_URLResponseInfo_GetBodyAsFileRef:i:l * + +replay 0 PPB_Messaging_PostMessage:iC: * + +# Register signatures found in all previous replay commands for export +# via install_upcalls +echo +echo "*** REGISTER REPLAY METHODS" +replay_activate + +# Create a upcall service on the channel between nexe and sel_univeral. +# The service string is save into the variable "service_string". +echo +echo "*** CREATE UPCALL SERVICE" +install_upcalls service_string pepper_desc +# the variable service string is very long and might change so we suppress it +nondeterministic s("${service_string}") @LENGTHY_SERVICE_STRING diff --git a/ppapi/native_client/tests/ppapi_simple_tests/test.txt b/ppapi/native_client/tests/ppapi_simple_tests/test.txt new file mode 100644 index 0000000..999a079 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_simple_tests/test.txt @@ -0,0 +1,5 @@ +Lorem ipsum dolor sit. Amet massa libero bibendum. Quis curabitur consectetuer eu. Sit mollis non euismod. Vel scelerisque volutpat interdum condimentum proin congue quis. Congue bibendum dolor ipsum. Hac purus nunc rhoncus. Odio inceptos nunc risus egestas non tempus neque. Mauris proin nibh ipsum mus risus pellentesque vitae. Etiam in duis eu tempor aliquet dolor ligula id aliquam vel lectus. Mi wisi ipsum commodo. Adipisci sodales vestibulum aliquam. Nonummy ligula nisl amet. Id et rutrum pede ornare arcu ornare senectus taciti sollicitudin in dictum class nulla mi in. Sed sodales risus fermentum. Ipsum hendrerit aliquam adipisci nunc nam curabitur sed. Dictum netus maecenas pellentesque. Cursus metus libero magnis. Pellentesque dictumst per aliquam. Elementum dis urna et. Ad in non in. A nisl bibendum faucibus. Egestas dictum lacinia condimentum. Sapien neque quisque quisque libero aliquet molestie et. Semper maecenas justo molestie. Dis in duis congue. Id sem hac ornare libero turpis conubia eget repudiandae mi enim nec adipiscing mollis phasellus wisi. + +Viverra elit egestas nulla. Viverra pulvinar in molestie. Wisi odio tincidunt odio. Diam ac erat arcu. Nulla odio commodo quam. Non curabitur mollis ac. Fermentum mauris consectetuer hendrerit massa vivamus amet nullam. Cursus felis sollicitudin condimentum lectus id amet suspendisse. Nunc eros non risus. Orci nec in magna. Ut nulla phasellus nec cursus leo mi semper. Id vestibulum eget sed. Arcu erat nec proin curabitur felis accumsan dolor enim quis mauris aliquip adipisicing volutpat odio molestie. Eu pulvinar amet lacinia. + +Pellentesque scelerisque mauris ut quis sed non aut. Metus cursus nulla cras. Vivamus duis sit mauris. Sapien urna amet wisi quam gravida sit venenatis. Tortor vel amet neque eu inceptos sit aliquam fusce id volutpat tristique. Phasellus sit mattis nisl. Dui eu senectus ligula. Quia justo sit consequat erat aenean interdum urna. Scelerisque diam ac urna. Pellentesque vitae aliquet maecenas. diff --git a/ppapi/native_client/tests/ppapi_test_example/nacl.scons b/ppapi/native_client/tests/ppapi_test_example/nacl.scons new file mode 100644 index 0000000..293d2a1 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_test_example/nacl.scons @@ -0,0 +1,47 @@ +# -*- python -*- +# 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. +# +# This test demonstrates sample usage of ppapi_test_lib. +# +# These ppapi_test_lib/ headers should be used by the test setup: +# test_interface.h - test interface + setup to be implemented by the tester. +# get_browser_interface.h - provides getters for proxy-supported interfaces. +# +# ppapi_test_example.cc - sample implementation test_interface.h. +# ppapi_test_example.html - sample test driver that uses scripting. +# ppapi_test_example.js - setup for sample test driver. +# ppapi_test_example.nmf - sample manifest for platform-specific nexes. + +Import('env') + +env.Prepend(CPPDEFINES=['XP_UNIX']) + +nexe = 'ppapi_test_example_%s' % env.get('TARGET_FULLARCH') +env.Alias('ppapi_test_example${PROGSUFFIX}', + ['$STAGING_DIR/%s${PROGSUFFIX}' % nexe]) + +ppapi_test_example_nexe = env.ComponentProgram( + nexe, + ['ppapi_test_example.cc'], + EXTRA_LIBS=['${PPAPI_LIBS}', + 'ppapi_test_lib', + 'platform', # for CHECK + 'pthread', + 'gio', + ]) + +env.Publish(nexe, 'run', + ['ppapi_test_example.html', + 'ppapi_test_example.nmf', + 'ppapi_test_example.js']) + +node = env.PPAPIBrowserTester('ppapi_test_example_browser_test.out', + url='ppapi_test_example.html', + files=env.ExtractPublishedFiles(nexe)) + +env.AddNodeToTestSuite(node, + ['chrome_browser_tests'], + 'run_ppapi_test_example_browser_test', + is_broken=env.PPAPIBrowserTesterIsBroken()) diff --git a/ppapi/native_client/tests/ppapi_test_example/ppapi_test_example.cc b/ppapi/native_client/tests/ppapi_test_example/ppapi_test_example.cc new file mode 100644 index 0000000..5fd7c78 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_test_example/ppapi_test_example.cc @@ -0,0 +1,46 @@ +// 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 <string.h> + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/tests/ppapi_test_lib/get_browser_interface.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" + +#include "ppapi/c/pp_bool.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/ppb_core.h" + +namespace { + +void Callback(void* /*data*/, int32_t /*result*/) { + printf("--- Callback\n"); +} + +void TestSimple() { + printf("--- TestSimple\n"); + EXPECT(pp_instance() != kInvalidInstance); + EXPECT(pp_module() != kInvalidModule); + TEST_PASSED; +} + +void TestCallback() { + printf("--- TestCallback\n"); + PP_CompletionCallback callback = MakeTestableCompletionCallback( + "Callback", Callback, NULL /*user_data*/); + PPBCore()->CallOnMainThread(10, callback, PP_OK); + TEST_PASSED; +} + +} // namespace + +void SetupTests() { + RegisterTest("TestSimple", TestSimple); + RegisterTest("TestCallback", TestCallback); +} + +void SetupPluginInterfaces() { + // TODO(polina): add an example of PPP interface testing +} diff --git a/ppapi/native_client/tests/ppapi_test_example/ppapi_test_example.html b/ppapi/native_client/tests/ppapi_test_example/ppapi_test_example.html new file mode 100644 index 0000000..76917bc --- /dev/null +++ b/ppapi/native_client/tests/ppapi_test_example/ppapi_test_example.html @@ -0,0 +1,31 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + <!-- Copyright (c) 2011 Google Inc. All rights reserved. --> + <head> + <meta http-equiv="Pragma" content="no-cache" /> + <meta http-equiv="Expires" content="-1" /> + <script type="text/javascript" src="nacltest.js"></script> + <!-- TODO(tester): change JavaScript file name --> + <script type="text/javascript" src="ppapi_test_example.js"></script> + <title>PPAPI Test Example</title> <!-- TODO(tester): change title --> + </head> + <body> + <h1>PPAPI Test Example</h1> <!-- TODO(tester): change heading --> + + <!-- TODO(tester): change manifest file name --> + <embed type="application/x-nacl" id="test_nexe" + name="nacl_module" + src="ppapi_test_example.nmf" + width="0" height="0" /> + + <script type="text/javascript"> + //<![CDATA[ + var tester = new Tester(); + setupTests(tester, $('test_nexe')); + tester.waitFor($('test_nexe')); + tester.run(); + //]]> + </script> + </body> +</html> diff --git a/ppapi/native_client/tests/ppapi_test_example/ppapi_test_example.js b/ppapi/native_client/tests/ppapi_test_example/ppapi_test_example.js new file mode 100644 index 0000000..5ff9dec --- /dev/null +++ b/ppapi/native_client/tests/ppapi_test_example/ppapi_test_example.js @@ -0,0 +1,41 @@ +// 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. + +function setupTests(tester, plugin) { + // TODO(tester): replace with your tests. + + // Below are sample test cases demonstrating postMessage as the test + // driving mechanism. + + tester.addAsyncTest('Example::Simple', function(status) { + var messageListener = status.wrap(function(message) { + status.log('Received message: ' + message.data); + plugin.removeEventListener('message', messageListener, false); + status.assertEqual(message.data, 'TestSimple:PASSED'); + status.pass(); + }); + + plugin.addEventListener("message", messageListener, false); + plugin.postMessage("TestSimple"); + }); + + tester.addAsyncTest('Example::Callback', function(status) { + var gotPassed = false; + var messageListener = status.wrap(function(message) { + status.log('Received message: ' + message.data); + plugin.removeEventListener('message', messageListener, false); + if (!gotPassed) { + status.assertEqual(message.data, 'TestCallback:PASSED'); + gotPassed = true; + plugin.addEventListener("message", messageListener, false); + } else { + status.assertEqual(message.data, 'Callback'); + status.pass(); + } + }); + + plugin.addEventListener("message", messageListener, false); + plugin.postMessage("TestCallback"); + }); +} diff --git a/ppapi/native_client/tests/ppapi_test_example/ppapi_test_example.nmf b/ppapi/native_client/tests/ppapi_test_example/ppapi_test_example.nmf new file mode 100644 index 0000000..8d9dd98 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_test_example/ppapi_test_example.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-32": {"url": "ppapi_test_example_x86-32.nexe"}, + "x86-64": {"url": "ppapi_test_example_x86-64.nexe"}, + "arm": {"url": "ppapi_test_example_arm.nexe"} + } +} diff --git a/ppapi/native_client/tests/ppapi_test_lib/get_browser_interface.cc b/ppapi/native_client/tests/ppapi_test_lib/get_browser_interface.cc new file mode 100644 index 0000000..3153e61 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_test_lib/get_browser_interface.cc @@ -0,0 +1,179 @@ +// 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/platform/nacl_check.h" + +#include "ppapi/c/dev/ppb_context_3d_dev.h" +#include "ppapi/c/dev/ppb_cursor_control_dev.h" +#include "ppapi/c/dev/ppb_font_dev.h" +#include "ppapi/c/dev/ppb_graphics_3d_dev.h" +#include "ppapi/c/dev/ppb_memory_dev.h" +#include "ppapi/c/dev/ppb_opengles_dev.h" +#include "ppapi/c/dev/ppb_scrollbar_dev.h" +#include "ppapi/c/dev/ppb_surface_3d_dev.h" +#include "ppapi/c/dev/ppb_testing_dev.h" +#include "ppapi/c/dev/ppb_var_deprecated.h" +#include "ppapi/c/dev/ppb_widget_dev.h" +#include "ppapi/c/ppb_core.h" +#include "ppapi/c/ppb_file_io.h" +#include "ppapi/c/ppb_file_ref.h" +#include "ppapi/c/ppb_file_system.h" +#include "ppapi/c/ppb_graphics_2d.h" +#include "ppapi/c/ppb_image_data.h" +#include "ppapi/c/ppb_input_event.h" +#include "ppapi/c/ppb_instance.h" +#include "ppapi/c/ppb_messaging.h" +#include "ppapi/c/ppb_url_loader.h" +#include "ppapi/c/ppb_url_request_info.h" +#include "ppapi/c/ppb_url_response_info.h" +#include "ppapi/c/ppb_var.h" + +#include "native_client/tests/ppapi_test_lib/get_browser_interface.h" +#include "native_client/tests/ppapi_test_lib/internal_utils.h" + +const void* GetBrowserInterface(const char* interface_name) { + return (*ppb_get_interface())(interface_name); +} + +const void* GetBrowserInterfaceSafe(const char* interface_name) { + const void* ppb_interface = (*ppb_get_interface())(interface_name); + CHECK(ppb_interface != NULL); + return ppb_interface; +} + +// Stable interfaces. + +const PPB_Core* PPBCore() { + return reinterpret_cast<const PPB_Core*>( + GetBrowserInterfaceSafe(PPB_CORE_INTERFACE)); +} + +const PPB_FileIO* PPBFileIO() { + return reinterpret_cast<const PPB_FileIO*>( + GetBrowserInterface(PPB_FILEIO_INTERFACE)); +} + +const PPB_FileRef* PPBFileRef() { + return reinterpret_cast<const PPB_FileRef*>( + GetBrowserInterface(PPB_FILEREF_INTERFACE)); +} + +const PPB_FileSystem* PPBFileSystem() { + return reinterpret_cast<const PPB_FileSystem*>( + GetBrowserInterface(PPB_FILESYSTEM_INTERFACE)); +} + +const PPB_Graphics2D* PPBGraphics2D() { + return reinterpret_cast<const PPB_Graphics2D*>( + GetBrowserInterfaceSafe(PPB_GRAPHICS_2D_INTERFACE)); +} + +const PPB_ImageData* PPBImageData() { + return reinterpret_cast<const PPB_ImageData*>( + GetBrowserInterfaceSafe(PPB_IMAGEDATA_INTERFACE)); +} + +const PPB_InputEvent* PPBInputEvent() { + return reinterpret_cast<const PPB_InputEvent*>( + GetBrowserInterfaceSafe(PPB_INPUT_EVENT_INTERFACE)); +} + +const PPB_Instance* PPBInstance() { + return reinterpret_cast<const PPB_Instance*>( + GetBrowserInterfaceSafe(PPB_INSTANCE_INTERFACE)); +} + +const PPB_KeyboardInputEvent* PPBKeyboardInputEvent() { + return reinterpret_cast<const PPB_KeyboardInputEvent*>( + GetBrowserInterfaceSafe(PPB_KEYBOARD_INPUT_EVENT_INTERFACE)); +} + +const PPB_Messaging* PPBMessaging() { + return reinterpret_cast<const PPB_Messaging*>( + GetBrowserInterfaceSafe(PPB_MESSAGING_INTERFACE)); +} + +const PPB_MouseInputEvent* PPBMouseInputEvent() { + return reinterpret_cast<const PPB_MouseInputEvent*>( + GetBrowserInterfaceSafe(PPB_MOUSE_INPUT_EVENT_INTERFACE)); +} + +const PPB_URLLoader* PPBURLLoader() { + return reinterpret_cast<const PPB_URLLoader*>( + GetBrowserInterfaceSafe(PPB_URLLOADER_INTERFACE)); +} + +const PPB_URLRequestInfo* PPBURLRequestInfo() { + return reinterpret_cast<const PPB_URLRequestInfo*>( + GetBrowserInterfaceSafe(PPB_URLREQUESTINFO_INTERFACE)); +} + +const PPB_URLResponseInfo* PPBURLResponseInfo() { + return reinterpret_cast<const PPB_URLResponseInfo*>( + GetBrowserInterfaceSafe(PPB_URLRESPONSEINFO_INTERFACE)); +} + +const PPB_Var* PPBVar() { + return reinterpret_cast<const PPB_Var*>( + GetBrowserInterfaceSafe(PPB_VAR_INTERFACE)); +} + +const PPB_WheelInputEvent* PPBWheelInputEvent() { + return reinterpret_cast<const PPB_WheelInputEvent*>( + GetBrowserInterfaceSafe(PPB_WHEEL_INPUT_EVENT_INTERFACE)); +} + + +// Dev interfaces. + +const PPB_Context3D_Dev* PPBContext3DDev() { + return reinterpret_cast<const PPB_Context3D_Dev*>( + GetBrowserInterface(PPB_CONTEXT_3D_DEV_INTERFACE)); +} + +const PPB_CursorControl_Dev* PPBCursorControlDev() { + return reinterpret_cast<const PPB_CursorControl_Dev*>( + GetBrowserInterface(PPB_CURSOR_CONTROL_DEV_INTERFACE)); +} + +const PPB_Graphics3D_Dev* PPBGraphics3DDev() { + return reinterpret_cast<const PPB_Graphics3D_Dev*>( + GetBrowserInterface(PPB_GRAPHICS_3D_DEV_INTERFACE)); +} + +const PPB_Font_Dev* PPBFontDev() { + return reinterpret_cast<const PPB_Font_Dev*>( + GetBrowserInterface(PPB_FONT_DEV_INTERFACE)); +} + +const PPB_Memory_Dev* PPBMemoryDev() { + return reinterpret_cast<const PPB_Memory_Dev*>( + GetBrowserInterface(PPB_MEMORY_DEV_INTERFACE)); +} + +const PPB_OpenGLES2_Dev* PPBOpenGLES2Dev() { + return reinterpret_cast<const PPB_OpenGLES2_Dev*>( + GetBrowserInterface(PPB_OPENGLES2_DEV_INTERFACE)); +} + +const PPB_Scrollbar_Dev* PPBScrollbarDev() { + return reinterpret_cast<const PPB_Scrollbar_Dev*>( + GetBrowserInterface(PPB_SCROLLBAR_DEV_INTERFACE)); +} + +const PPB_Surface3D_Dev* PPBSurface3DDev() { + return reinterpret_cast<const PPB_Surface3D_Dev*>( + GetBrowserInterface(PPB_SURFACE_3D_DEV_INTERFACE)); +} + +const PPB_Testing_Dev* PPBTestingDev() { + return reinterpret_cast<const PPB_Testing_Dev*>( + GetBrowserInterface(PPB_TESTING_DEV_INTERFACE)); +} + +const PPB_Widget_Dev* PPBWidgetDev() { + return reinterpret_cast<const PPB_Widget_Dev*>( + GetBrowserInterface(PPB_WIDGET_DEV_INTERFACE)); +} + diff --git a/ppapi/native_client/tests/ppapi_test_lib/get_browser_interface.h b/ppapi/native_client/tests/ppapi_test_lib/get_browser_interface.h new file mode 100644 index 0000000..2db1e04 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_test_lib/get_browser_interface.h @@ -0,0 +1,85 @@ +// 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. +// +// Defines helper functions for all interfaces supported by the Native Client +// proxy. + +#ifndef NATIVE_CLIENT_TESTS_PPAPI_TEST_PPB_TEMPLATE_GET_BROWSER_INTERFACE_H +#define NATIVE_CLIENT_TESTS_PPAPI_TEST_PPB_TEMPLATE_GET_BROWSER_INTERFACE_H + +// The definition of scrollbar depends on the interface version. +// TODO(brettw) either move all interfaces to this method, or encode all +// versions explicitly in all interfaces. +#include "ppapi/c/dev/ppb_scrollbar_dev.h" + +struct PPB_Context3D_Dev; +struct PPB_Core; +struct PPB_CursorControl_Dev; +struct PPB_FileIO; +struct PPB_FileRef; +struct PPB_FileSystem; +struct PPB_Font_Dev; +struct PPB_Graphics2D; +struct PPB_Graphics3D_Dev; +struct PPB_ImageData; +struct PPB_InputEvent; +struct PPB_Instance; +struct PPB_KeyboardInputEvent; +struct PPB_Memory_Dev; +struct PPB_Messaging; +struct PPB_MouseInputEvent; +struct PPB_OpenGLES2_Dev; +struct PPB_Surface3D_Dev; +struct PPB_Testing_Dev; +struct PPB_URLLoader; +struct PPB_URLRequestInfo; +struct PPB_URLResponseInfo; +struct PPB_Var; +struct PPB_WheelInputEvent; +struct PPB_Widget_Dev; + +// Looks up the interface and returns its pointer or NULL. +const void* GetBrowserInterface(const char* interface_name); +// Uses GetBrowserInterface() and CHECKs for NULL. +const void* GetBrowserInterfaceSafe(const char* interface_name); + +// +// Stable interfaces. +// Lookup guarantees that the interface is available by using NULL CHECKs. +// + +const PPB_Core* PPBCore(); +const PPB_FileIO* PPBFileIO(); +const PPB_FileRef* PPBFileRef(); +const PPB_FileSystem* PPBFileSystem(); +const PPB_Graphics2D* PPBGraphics2D(); +const PPB_ImageData* PPBImageData(); +const PPB_InputEvent* PPBInputEvent(); +const PPB_Instance* PPBInstance(); +const PPB_KeyboardInputEvent* PPBKeyboardInputEvent(); +const PPB_Messaging* PPBMessaging(); +const PPB_MouseInputEvent* PPBMouseInputEvent(); +const PPB_URLLoader* PPBURLLoader(); +const PPB_URLRequestInfo* PPBURLRequestInfo(); +const PPB_URLResponseInfo* PPBURLResponseInfo(); +const PPB_Var* PPBVar(); +const PPB_WheelInputEvent* PPBWheelInputEvent(); + +// +// Experimental (aka Dev) interfaces. +// Lookup returns NULL if the interface is not available. +// + +const PPB_Context3D_Dev* PPBContext3DDev(); +const PPB_CursorControl_Dev* PPBCursorControlDev(); +const PPB_Font_Dev* PPBFontDev(); +const PPB_Graphics3D_Dev* PPBGraphics3DDev(); +const PPB_Memory_Dev* PPBMemoryDev(); +const PPB_OpenGLES2_Dev* PPBOpenGLES2Dev(); +const PPB_Scrollbar_Dev* PPBScrollbarDev(); +const PPB_Surface3D_Dev* PPBSurface3DDev(); +const PPB_Testing_Dev* PPBTestingDev(); +const PPB_Widget_Dev* PPBWidgetDev(); + +#endif // NATIVE_CLIENT_TESTS_PPAPI_TEST_PPB_TEMPLATE_GET_BROWSER_INTERFACE_H diff --git a/ppapi/native_client/tests/ppapi_test_lib/internal_utils.cc b/ppapi/native_client/tests/ppapi_test_lib/internal_utils.cc new file mode 100644 index 0000000..2ca3fe8 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_test_lib/internal_utils.cc @@ -0,0 +1,22 @@ +// 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/tests/ppapi_test_lib/internal_utils.h" + +namespace { + +PP_Module global_pp_module = 0; +PP_Instance global_pp_instance = 0; +PPB_GetInterface global_ppb_get_interface = NULL; + +} // namespace + +void set_ppb_get_interface(PPB_GetInterface get_interface) { + global_ppb_get_interface = get_interface; +} +void set_pp_instance(PP_Instance instance) { global_pp_instance = instance; } +void set_pp_module(PP_Module module) { global_pp_module = module; } +PPB_GetInterface ppb_get_interface() { return global_ppb_get_interface; } +PP_Module pp_module() { return global_pp_module; } +PP_Instance pp_instance() { return global_pp_instance; } diff --git a/ppapi/native_client/tests/ppapi_test_lib/internal_utils.h b/ppapi/native_client/tests/ppapi_test_lib/internal_utils.h new file mode 100644 index 0000000..c2b5cfe --- /dev/null +++ b/ppapi/native_client/tests/ppapi_test_lib/internal_utils.h @@ -0,0 +1,31 @@ +// 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. +// +// This is an internal header. Do not include in your test implementation. + +#ifndef NATIVE_CLIENT_TESTS_PPAPI_TEST_PPB_TEMPLATE_INTERNAL_UTILS_H +#define NATIVE_CLIENT_TESTS_PPAPI_TEST_PPB_TEMPLATE_INTERNAL_UTILS_H + +#include "native_client/src/include/nacl_string.h" + +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/pp_var.h" +#include "ppapi/c/ppb.h" + +void set_ppb_get_interface(PPB_GetInterface get_interface); +void set_pp_instance(PP_Instance instance); +void set_pp_module(PP_Module module); +PPB_GetInterface ppb_get_interface(); +PP_Module pp_module(); +PP_Instance pp_instance(); + +PP_Var GetScriptableObject(PP_Instance instance); + +bool HasScriptableTest(nacl::string test_name); +PP_Var RunScriptableTest(nacl::string test_name); + +void RunTest(nacl::string test_name); +#endif // NATIVE_CLIENT_TESTS_PPAPI_TEST_PPB_TEMPLATE_INTERNAL_UTILS_H diff --git a/ppapi/native_client/tests/ppapi_test_lib/module_instance.cc b/ppapi/native_client/tests/ppapi_test_lib/module_instance.cc new file mode 100644 index 0000000..ec8122f --- /dev/null +++ b/ppapi/native_client/tests/ppapi_test_lib/module_instance.cc @@ -0,0 +1,175 @@ +// 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. +// +// This implements the required interfaces for representing a plugin module +// instance in browser interactions and provides a way to register custom +// plugin interfaces. +// + +#include <stdio.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/tests/ppapi_test_lib/get_browser_interface.h" +#include "native_client/tests/ppapi_test_lib/internal_utils.h" +#include "native_client/tests/ppapi_test_lib/test_interface.h" + +#include "ppapi/c/dev/ppb_var_deprecated.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_var.h" +#include "ppapi/c/ppb.h" +#include "ppapi/c/ppb_var.h" +#include "ppapi/c/ppp.h" +#include "ppapi/c/ppp_instance.h" +#include "ppapi/c/ppp_messaging.h" + +/////////////////////////////////////////////////////////////////////////////// +// Plugin interface registration +/////////////////////////////////////////////////////////////////////////////// + +namespace { + +class PluginInterfaceTable { + public: + // Return singleton intsance. + static PluginInterfaceTable* Get() { + static PluginInterfaceTable table; + return &table; + } + + void AddInterface(const char* interface_name, const void* ppp_interface) { + interface_map_[nacl::string(interface_name)] = ppp_interface; + } + const void* GetInterface(const char* interface_name) { + // This will add a NULL element for missing interfaces. + return interface_map_[nacl::string(interface_name)]; + } + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(PluginInterfaceTable); + + PluginInterfaceTable() {} + + typedef std::map<nacl::string, const void*> InterfaceMap; + InterfaceMap interface_map_; +}; + +} // namespace + +void RegisterPluginInterface(const char* interface_name, + const void* ppp_interface) { + PluginInterfaceTable::Get()->AddInterface(interface_name, ppp_interface); +} + + +/////////////////////////////////////////////////////////////////////////////// +// PPP_Instance implementation +/////////////////////////////////////////////////////////////////////////////// + +PP_Bool DidCreateDefault(PP_Instance instance, + uint32_t /*argc*/, + const char* /*argn*/[], + const char* /*argv*/[]) { + CHECK(ppb_get_interface() != NULL); + CHECK(PPBCore() != NULL); + CHECK(PPBGraphics2D() != NULL); + CHECK(PPBImageData() != NULL); + CHECK(PPBInstance() != NULL); + CHECK(PPBMessaging() != NULL); + CHECK(PPBURLLoader() != NULL); + CHECK(PPBURLRequestInfo() != NULL); + CHECK(PPBURLResponseInfo() != NULL); + CHECK(PPBVar() != NULL); + + set_pp_instance(instance); + SetupTests(); + + return PP_TRUE; +} + +namespace { + +void DidDestroy(PP_Instance /*instance*/) { +} + +void DidChangeView(PP_Instance /*instance*/, + const struct PP_Rect* /*position*/, + const struct PP_Rect* /*clip*/) { +} + +void DidChangeFocus(PP_Instance /*instance*/, + PP_Bool /*has_focus*/) { +} + +PP_Bool HandleDocumentLoad(PP_Instance instance, + PP_Resource url_loader) { + return PP_TRUE; +} + +const PPP_Instance ppp_instance_interface = { + DidCreateDefault, + DidDestroy, + DidChangeView, + DidChangeFocus, + HandleDocumentLoad +}; + +/////////////////////////////////////////////////////////////////////////////// +// PPP_Messaging implementation +/////////////////////////////////////////////////////////////////////////////// + +void HandleMessage(PP_Instance instance, PP_Var message) { + if (message.type != PP_VARTYPE_STRING) + return; + uint32_t len = 0; + const char* test_name = PPBVar()->VarToUtf8(message, &len); + RunTest(test_name); +} + +const PPP_Messaging ppp_messaging_interface = { + HandleMessage +}; + +} // namespace + +/////////////////////////////////////////////////////////////////////////////// +// PPP implementation +/////////////////////////////////////////////////////////////////////////////// + +int32_t PPP_InitializeModule(PP_Module module, + PPB_GetInterface get_browser_interface) { + set_pp_module(module); + set_ppb_get_interface(get_browser_interface); + SetupPluginInterfaces(); + return PP_OK; +} + +void PPP_ShutdownModule() { +} + +const void* PPP_GetInterface(const char* interface_name) { + const void* ppp = PluginInterfaceTable::Get()->GetInterface(interface_name); + + // The PPP_Instance interface is required for every plugin, + // so supply one if the tester has not. + if (ppp == NULL && 0 == strncmp(PPP_INSTANCE_INTERFACE, interface_name, + strlen(PPP_INSTANCE_INTERFACE))) { + return &ppp_instance_interface; + } + // The PPP_Messaging interface is required for the test set-up, + // so we supply our own. + if (0 == strncmp(PPP_MESSAGING_INTERFACE, interface_name, + strlen(PPP_MESSAGING_INTERFACE))) { + CHECK(ppp == NULL); + return &ppp_messaging_interface; + } + // All other interfaces are to be optionally supplied by the tester, + // so we return whatever was added in SetupPluginInterfaces() (if anything). + return ppp; +} diff --git a/ppapi/native_client/tests/ppapi_test_lib/nacl.scons b/ppapi/native_client/tests/ppapi_test_lib/nacl.scons new file mode 100644 index 0000000..bb552b0 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_test_lib/nacl.scons @@ -0,0 +1,27 @@ +# -*- python -*- +# 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. +# +# Test library for testing PPAPI C layer for PPB_ and PPP_ interfaces. +# +# TODO(polina): also factor in the C++ layer? +# TODO(polina): add trusted build.scons. +# +# module_instance.cc - implements PPP and PPP_Instance interfaces. +# get_browser_interface.cc - implements interface lookup helpers. +# internal_utils.cc - implements internal helper functions and globals. +# test_interface.cc - implements the test interface. +# +# See ppapi_test_example for sample usage. + +Import('env') + +env.Prepend(CPPDEFINES=['XP_UNIX']) + +env.ComponentLibrary('ppapi_test_lib', + ['get_browser_interface.cc', + 'internal_utils.cc', + 'testable_callback.cc', + 'module_instance.cc', + 'test_interface.cc']); diff --git a/ppapi/native_client/tests/ppapi_test_lib/test_interface.cc b/ppapi/native_client/tests/ppapi_test_lib/test_interface.cc new file mode 100644 index 0000000..a1f0e90 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_test_lib/test_interface.cc @@ -0,0 +1,154 @@ +// 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/tests/ppapi_test_lib/test_interface.h" + +#include <string.h> +#include <map> +#include <new> + +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/shared/platform/nacl_check.h" +#include "native_client/tests/ppapi_test_lib/get_browser_interface.h" +#include "native_client/tests/ppapi_test_lib/internal_utils.h" + +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_var.h" +#include "ppapi/c/ppb_instance.h" +#include "ppapi/c/ppb_messaging.h" +#include "ppapi/c/ppb_var.h" + +void PostTestMessage(nacl::string test_name, nacl::string message) { + nacl::string test_message = test_name; + test_message += ":"; + test_message += message; + PP_Var post_var = PPBVar()->VarFromUtf8(pp_instance(), + test_message.c_str(), + test_message.size()); + PPBMessaging()->PostMessage(pp_instance(), post_var); + PPBVar()->Release(post_var); +} + +PP_Var PP_MakeString(const char* s) { + return PPBVar()->VarFromUtf8(pp_module(), s, strlen(s)); +} + +nacl::string StringifyVar(const PP_Var& var) { + uint32_t dummy_size; + switch (var.type) { + default: + return "<UNKNOWN>" + toString(var.type); + case PP_VARTYPE_NULL: + return "<NULL>"; + case PP_VARTYPE_BOOL: + return "<BOOL>" + toString(var.value.as_bool); + case PP_VARTYPE_INT32: + return "<INT32>" + toString(var.value.as_int); + case PP_VARTYPE_DOUBLE: + return "<DOUBLE>" + toString(var.value.as_double); + case PP_VARTYPE_STRING: + return "<STRING>" + nacl::string(PPBVar()->VarToUtf8(var, &dummy_size)); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// Test registration +//////////////////////////////////////////////////////////////////////////////// + +namespace { + +class TestTable { + public: + // Return singleton intsance. + static TestTable* Get() { + static TestTable table; + return &table; + } + + void AddTest(nacl::string test_name, TestFunction test_function) { + test_map_[test_name] = test_function; + } + void RunTest(nacl::string test_name); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(TestTable); + + TestTable() {} + + typedef std::map<nacl::string, TestFunction> TestMap; + TestMap test_map_; +}; + +void TestTable::RunTest(nacl::string test_name) { + TestMap::iterator it = test_map_.find(test_name); + if (it == test_map_.end()) { + PostTestMessage(test_name, "NOTFOUND"); + return; + } + CHECK(it->second != NULL); + TestFunction test_function = it->second; + return test_function(); +} + +} // namespace + +void RegisterTest(nacl::string test_name, TestFunction test_func) { + TestTable::Get()->AddTest(test_name, test_func); +} + +void RunTest(nacl::string test_name) { + TestTable::Get()->RunTest(test_name); +} + +//////////////////////////////////////////////////////////////////////////////// +// Testable callback support +//////////////////////////////////////////////////////////////////////////////// + +namespace { + +struct CallbackInfo { + nacl::string callback_name; + PP_CompletionCallback user_callback; +}; + +void ReportCallbackInvocationToJS(const char* callback_name) { + PP_Var callback_var = PPBVar()->VarFromUtf8(pp_module(), + callback_name, + strlen(callback_name)); + // Report using postmessage for async tests. + PPBMessaging()->PostMessage(pp_instance(), callback_var); + PPBVar()->Release(callback_var); +} + +void CallbackWrapper(void* user_data, int32_t result) { + CallbackInfo* callback_info = reinterpret_cast<CallbackInfo*>(user_data); + PP_RunCompletionCallback(&callback_info->user_callback, result); + ReportCallbackInvocationToJS(callback_info->callback_name.c_str()); + delete callback_info; +} + +} // namespace + +PP_CompletionCallback MakeTestableCompletionCallback( + const char* callback_name, // Tested for by JS harness. + PP_CompletionCallback_Func func, + void* user_data) { + CHECK(callback_name != NULL && strlen(callback_name) > 0); + CHECK(func != NULL); + + CallbackInfo* callback_info = new(std::nothrow) CallbackInfo; + CHECK(callback_info != NULL); + callback_info->callback_name = callback_name; + callback_info->user_callback = + PP_MakeOptionalCompletionCallback(func, user_data); + + return PP_MakeOptionalCompletionCallback(CallbackWrapper, callback_info); +} + +PP_CompletionCallback MakeTestableCompletionCallback( + const char* callback_name, // Tested for by JS harness. + PP_CompletionCallback_Func func) { + return MakeTestableCompletionCallback(callback_name, func, NULL); +} diff --git a/ppapi/native_client/tests/ppapi_test_lib/test_interface.h b/ppapi/native_client/tests/ppapi_test_lib/test_interface.h new file mode 100644 index 0000000..480bf27 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_test_lib/test_interface.h @@ -0,0 +1,175 @@ +// 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. +// +// Functions and constants for test registration and setup. +// +// NOTE: These must be implemented by the tester: +// - SetupTests() +// - SetupPluginInterfaces() +// +// Sample Usage: +// +// void MyCallback(void* user_data, int32_t result) { ... } +// +// void TestPPBFoo() { +// // sync test case +// PP_Resource my_resource = PPBFoo()->Create(kInvalidInstance); +// EXPECT(my_resource == kInvalidResource); +// +// // async test case +// PP_CompletionCallback testable_callback = +// MakeTestableCompletionCallback("MyCallback", MyCallback, NULL); +// int32_t pp_error = PPBFoo()->AsyncFunction(testable_callback); +// EXPECT(pp_error == PP_OK_COMPLETIONPENDING); +// +// TEST_PASSED; +// } +// +// void SetupTests() { +// RegisterTest("TestPPBFoo", TestPPBFoo); +// } +// +// const PPP_Bar ppp_bar_interface = { ... }; +// +// void SetupPluginInterface() { +// RegisterPluginInterface(PPP_BAR_INTERFACE, &ppp_bar_interface); +// } +// + +#ifndef NATIVE_CLIENT_TESTS_PPAPI_TEST_PPB_TEMPLATE_TEST_INTERFACE_H +#define NATIVE_CLIENT_TESTS_PPAPI_TEST_PPB_TEMPLATE_TEST_INTERFACE_H + +#include <stdio.h> +#include <limits> + +#include <sstream> + +#include "native_client/src/include/nacl_string.h" + +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/pp_var.h" + +//////////////////////////////////////////////////////////////////////////////// +// These must be implemented by the tester +//////////////////////////////////////////////////////////////////////////////// + +// Use RegisterTest() to register each TestFunction. +void SetupTests(); +// Use RegisterPluginInterface() to register custom PPP_ interfaces other than +// PPP_Instance that is required and provided by default. +void SetupPluginInterfaces(); + +//////////////////////////////////////////////////////////////////////////////// +// Test helpers +//////////////////////////////////////////////////////////////////////////////// + +// Registers test_function, so it is callable from JS using +// plugin.postMessage(test_name); +typedef void (*TestFunction)(); +void RegisterTest(nacl::string test_name, TestFunction test_function); + +// Registers ppp_interface, so it is returned by PPP_GetInterface(). +void RegisterPluginInterface(const char* interface_name, + const void* ppp_interface); + +// Helper for creating user callbacks whose invocation will be reported to JS. +// Callback setting allows for synchronous completion to make it easier to +// test error conditions. +// WARNING: Do not reuse this callback if the operation that took it as an arg +// returned PP_OK_COMPLETIONPENDING. The wrapper allocates data on creation +// and then deallocates it when the callback is invoked. +PP_CompletionCallback MakeTestableCompletionCallback( + const char* callback_name, // will be postmessage'ed to JS + PP_CompletionCallback_Func func, + void* user_data); +PP_CompletionCallback MakeTestableCompletionCallback( + const char* callback_name, // will be postmessage'ed to JS + PP_CompletionCallback_Func func); + +// Uses PPB_Messaging interface to post "test_name:message". +void PostTestMessage(nacl::string test_name, nacl::string message); + +// Make a STRING var. +PP_Var PP_MakeString(const char* s); + +// Convert var into printable string (for debuggin) +nacl::string StringifyVar(const PP_Var& var); + +// Use to verify the result of a test and report failures. +#define EXPECT(expr) do { \ + if (!(expr)) { \ + char error[1024]; \ + snprintf(error, sizeof(error), \ + "ERROR at %s:%d: %s\n", __FILE__, __LINE__, #expr); \ + fprintf(stderr, "%s", error); \ + PostTestMessage(__FUNCTION__, error); \ + } \ +} while (0) + +// Check expected value of INT32 var. +#define EXPECT_VAR_INT(var, val) \ + EXPECT(var.type == PP_VARTYPE_INT32 && var.value.as_int == val) + +// Check expected value of STRING var (val is 'char*') +#define EXPECT_VAR_STRING(var, val) \ + do { \ + EXPECT(var.type == PP_VARTYPE_STRING); \ + uint32_t dummy_size; \ + const char* expected = PPBVar()->VarToUtf8(var, &dummy_size); \ + EXPECT(0 == strcmp(expected, val)); \ + } while (0) + +// Check expected value of BOOL var. +#define EXPECT_VAR_BOOL(var, val) \ + EXPECT(var.type == PP_VARTYPE_BOOL && var.value.as_bool == val) + +// Use to report success. +#define TEST_PASSED PostTestMessage(__FUNCTION__, "PASSED"); +// Or failure. +#define TEST_FAILED EXPECT(false) + +// Handy for use with LOG_TO_BROWSER() convert arbitrary objects into strings. +template<typename T> nacl::string toString(T v) { + std::stringstream s; + s << v; + return s.str(); +} + +// Log message for debugging or progress reporting purposes. +// If you use this with nacltest.js::expectMessageSequence +// it will not interfere with output used for correctness checking. +#define LOG_TO_BROWSER(message) PostTestMessage("@", message) + +// Cause a crash in a way that is guaranteed not to get optimized out by LLVM. +#define CRASH *(volatile int *) 0 = 0; + + +// Use this constant for stress testing +// (i.e. creating and using a large number of resources). +const int kManyResources = 1000; + +const PP_Instance kInvalidInstance = 0; +const PP_Module kInvalidModule = 0; +const PP_Resource kInvalidResource = 0; + +// These should not exist. +// Chrome uses the bottom 2 bits to differentiate between different id types. +// 00 - module, 01 - instance, 10 - resource, 11 - var. +const PP_Instance kNotAnInstance = 0xFFFFF0; +const PP_Resource kNotAResource = 0xAAAAA0; + +// Interface pointers and ids corresponding to this plugin; +// set at initialization/creation. +PP_Instance pp_instance(); +PP_Module pp_module(); + +// If you are providing your own version of PPP_Instance::DidCreate +// call this function to ensure proper test set-up. +PP_Bool DidCreateDefault(PP_Instance instance, + uint32_t argc, const char* argn[], const char* argv[]); + +#endif // NATIVE_CLIENT_TESTS_PPAPI_TEST_PPB_TEMPLATE_TEST_INTERFACE_H diff --git a/ppapi/native_client/tests/ppapi_test_lib/testable_callback.cc b/ppapi/native_client/tests/ppapi_test_lib/testable_callback.cc new file mode 100644 index 0000000..453ea59 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_test_lib/testable_callback.cc @@ -0,0 +1,53 @@ +// 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 "ppapi/c/dev/ppb_testing_dev.h" +#include "ppapi/c/pp_errors.h" +#include "native_client/tests/ppapi_test_lib/get_browser_interface.h" +#include "native_client/tests/ppapi_test_lib/testable_callback.h" + +TestableCallback::TestableCallback(PP_Instance instance, bool force_async) + : have_result_(false), + result_(PP_OK_COMPLETIONPENDING), + force_async_(force_async), + post_quit_task_(false), + run_count_(0), + instance_(instance) { +} + +int32_t TestableCallback::WaitForResult() { + if (!have_result_) { + result_ = PP_OK_COMPLETIONPENDING; // Reset + post_quit_task_ = true; + + // This waits until PPBTestingDev()->QuitMessageLoop() is called + // by the "Handler" which represents the actual callback code. + PPBTestingDev()->RunMessageLoop(instance_); + } + have_result_ = false; + return result_; +} + +PP_CompletionCallback TestableCallback::GetCallback() { + int32_t flags = force_async_ ? 0 : PP_COMPLETIONCALLBACK_FLAG_OPTIONAL; + PP_CompletionCallback cc = + PP_MakeCompletionCallback(&TestableCallback::Handler, this); + cc.flags = flags; + return cc; +} + +// static, so we can take it's address +// This is the actual callback, all it does is record +// the result and wake up whoever is block on +// "WaitForResult" +void TestableCallback::Handler(void* user_data, int32_t result) { + TestableCallback* callback = static_cast<TestableCallback*>(user_data); + callback->result_ = result; + callback->have_result_ = true; + ++callback->run_count_; + if (callback->post_quit_task_) { + callback->post_quit_task_ = false; + PPBTestingDev()->QuitMessageLoop(callback->instance_); + } +} diff --git a/ppapi/native_client/tests/ppapi_test_lib/testable_callback.h b/ppapi/native_client/tests/ppapi_test_lib/testable_callback.h new file mode 100644 index 0000000..56451ab --- /dev/null +++ b/ppapi/native_client/tests/ppapi_test_lib/testable_callback.h @@ -0,0 +1,65 @@ +// 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. + +#ifndef NATIVE_CLIENT_TESTS_PPAPI_TEST_LIB_TESTABLE_CALLBACK_H +#define NATIVE_CLIENT_TESTS_PPAPI_TEST_LIB_TESTABLE_CALLBACK_H + +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_stdint.h" + +// NOTE: if you use you TestableCallback you will need to enable +// testing interfaces in PPAPIBrowserTester(), e.g. +// "--enable-pepper-testing", c.f. +// tests/ppapi_browser/ppb_graphics2d/nacl.scons +// +// Example Usage: +// +// void TestProgressSimple() { +// TestableCallback callback(pp_instance(), true); +// ... +// rv = PPBURLLoader()->Open(loader, request, callback.GetCallback()); +// EXPECT(rv == PP_OK_COMPLETIONPENDING); + +// rv = callback.WaitForResult(); +// EXPECT(rv == PP_OK); +// ... +// } + +class TestableCallback { + public: + TestableCallback(PP_Instance instance, bool force_async); + + // Get the callback to be passed to an asynchronous PPAPI call + PP_CompletionCallback GetCallback(); + + // Waits for the callback to be called and returns the + // result. Returns immediately if the callback was previously called + // and the result wasn't returned (i.e. each result value received + // by the callback is returned by WaitForResult() once and only + // once). + int32_t WaitForResult(); + + bool HasRun() const { return run_count_ != 0; } + + // Make instance runnable again. + void Reset() { + run_count_ = 0; + have_result_ = false; + } + + int32_t Result() const { return result_; } + + private: + static void Handler(void* user_data, int32_t result); + + bool have_result_; // is a result available? + int32_t result_; // value of the result + bool force_async_; // force callback to be always called + bool post_quit_task_; // has cleanup beem performed + unsigned run_count_; // number of times the callback has been called + PP_Instance instance_; +}; + +#endif // NATIVE_CLIENT_TESTS_PPAPI_TEST_LIB_TESTABLE_CALLBACK_H diff --git a/ppapi/native_client/tests/ppapi_tests/build.scons b/ppapi/native_client/tests/ppapi_tests/build.scons new file mode 100644 index 0000000..a1e496d --- /dev/null +++ b/ppapi/native_client/tests/ppapi_tests/build.scons @@ -0,0 +1,45 @@ +# -*- python -*- +# Copyright 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. + +# A way to build the PPAPI tests as a trusted plugin to validate directly +# against Chrome on Linux using these arguments: +# --register-pepper-plugins=\ +# "/path/to/libppapi_tests_<ARCH>.so;application/x-nacl" +# --enable-pepper-testing \ +# http://localhost:5103/scons-out/nacl-x86-../staging/test_case.html +# Tip: you can verify that the plugin was loaded by navigating to about:plugins +# in Chromium. + +# Also see nacl.scons for building/running (a subset of) these tests in NaCl. + +Import('env') + +if env.Bit('linux'): + env['COMPONENT_STATIC'] = False # Build a .so, not a .a + + # Adjust CCFLAGS to match the more forgiving standards used in the Chromium + # PPAPI tests. + env.FilterOut(CCFLAGS=['-Werror', '-pedantic']) + env.Append(CCFLAGS=['-Wno-unused-parameter', + '-Wno-missing-field-initializers', + '-Wall']) + ppapi_tests_trusted = 'libppapi_tests_%s.so' % env.get('TARGET_FULLARCH') + + libppapi_tests_so = env.ComponentLibrary( + ppapi_tests_trusted, + Glob('${SOURCE_ROOT}/ppapi/tests/*.cc'), + EXTRA_LIBS=['ppapi_cpp'], + no_import_lib=True) + + env.Publish(ppapi_tests_trusted, 'run', + ['${SOURCE_ROOT}/ppapi/tests/test_url_loader_data/*'], + subdir='test_url_loader_data') + + env.Publish(ppapi_tests_trusted, 'run', + [libppapi_tests_so, + '${SOURCE_ROOT}/ppapi/tests/test_case.html', + 'test_case.nmf', + '${SOURCE_ROOT}/ppapi/tests/test_image_data', + '${SOURCE_ROOT}/ppapi/tests/test_page.css']) diff --git a/ppapi/native_client/tests/ppapi_tests/nacl.scons b/ppapi/native_client/tests/ppapi_tests/nacl.scons new file mode 100644 index 0000000..685ddc8 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_tests/nacl.scons @@ -0,0 +1,105 @@ +# -*- python -*- +# 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. + +Import('env') +import os + +ppapi_tests_target = 'ppapi_tests_${TARGET_FULLARCH}' + +ppapi_tests_sources = [ + # Common test files + 'test_case.cc', + 'test_utils.cc', + 'testing_instance.cc', + + # Compile-time tests + 'test_c_includes.c', + 'test_cpp_includes.cc', + 'test_struct_sizes.c', + + # Test cases (PLEASE KEEP THIS SECTION IN ALPHABETICAL ORDER) + # Add/uncomment PPAPI interfaces below when they get proxied. + # Not yet proxied. + #'test_broker.cc', + # Not yet proxied. + #'test_buffer.cc', + # Not yet proxied. + #'test_char_set.cc', + 'test_cursor_control.cc', + # Fails in DeleteDirectoryRecursively. + # BUG: http://code.google.com/p/nativeclient/issues/detail?id=2107 + #'test_directory_reader.cc', + 'test_file_io.cc', + 'test_file_ref.cc', + 'test_file_system.cc', + 'test_memory.cc', + 'test_graphics_2d.cc', + 'test_image_data.cc', + 'test_paint_aggregator.cc', + # test_post_message.cc relies on synchronous scripting, which is not + # available for untrusted tests. + # Does not compile under nacl (uses private interface ExecuteScript). + #'test_post_message.cc', + 'test_scrollbar.cc', + # Not yet proxied. + #'test_transport.cc', + # Not yet proxied. + #'test_uma.cc', + # Activating the URL loader test requires a test httpd that + # understands HTTP POST, which our current httpd.py doesn't. + # It also requires deactivating the tests that use FileIOTrusted + # when running in NaCl. + #'test_url_loader.cc', + # Does not compile under nacl (uses VarPrivate). + #'test_url_util.cc', + # Not yet proxied. + #'test_video_decoder.cc', + 'test_var.cc', + + # Deprecated test cases. + #'test_instance_deprecated.cc', + # Var_deprecated fails in TestPassReference, and we probably won't + # fix it. + #'test_var_deprecated.cc' + ] + +# Pepper code has small issues like extra commas at the end of enums. +env.FilterOut(CFLAGS=['-pedantic']) +env.FilterOut(CCFLAGS=['-pedantic']) + +# This abstracts away that we are including sources from another +# directory. It is also necessary to work around a scons bug that +# causes object files to end up in the wrong directory. +def MakeComponentObject(src): + return env.ComponentObject( + os.path.splitext(src)[0], + os.path.join('$SOURCE_ROOT/ppapi/tests', src)) + +ppapi_tests_objs = [MakeComponentObject(src) for src in ppapi_tests_sources] + +ppapi_tests_nexe = env.ComponentProgram(ppapi_tests_target, + ppapi_tests_objs, + EXTRA_LIBS=['${PPAPI_LIBS}', + 'ppapi_cpp' + ]) + +# Note that the html is required to run this program. +# To run, load page with mode=nacl search string: +# http://localhost:5103/scons-out/nacl-x86-32/staging/test_case.html?mode=nacl +# http://localhost:5103/scons-out/nacl-x86-64/staging/test_case.html?mode=nacl + +# NOTE: This test is also run as part of the pyauto suite. +# See pyauto_nacl/nacl.scons. + +env.Publish(ppapi_tests_target, 'run', + ['$SOURCE_ROOT/ppapi/tests/test_url_loader_data/*'], + subdir='test_url_loader_data') + +env.Publish(ppapi_tests_target, 'run', + [ppapi_tests_nexe, + '$SOURCE_ROOT/ppapi/tests/test_case.html', + 'test_case.nmf', + '$SOURCE_ROOT/ppapi/tests/test_image_data', + '$SOURCE_ROOT/ppapi/tests/test_page.css']) diff --git a/ppapi/native_client/tests/ppapi_tests/test_case.nmf b/ppapi/native_client/tests/ppapi_tests/test_case.nmf new file mode 100644 index 0000000..3528855 --- /dev/null +++ b/ppapi/native_client/tests/ppapi_tests/test_case.nmf @@ -0,0 +1,7 @@ +{ + "program": { + "x86-64": {"url": "ppapi_tests_x86-64.nexe"}, + "x86-32": {"url": "ppapi_tests_x86-32.nexe"}, + "arm": {"url": "ppapi_tests_arm.nexe"} + } +} |