blob: b340ecad80c1b85a2b1173d24ff3a378608606ce [file] [log] [blame]
// 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.
#include "ppapi/proxy/resource_creation_proxy.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/pp_size.h"
#include "ppapi/proxy/interface_id.h"
#include "ppapi/proxy/plugin_dispatcher.h"
#include "ppapi/c/trusted/ppb_image_data_trusted.h"
#include "ppapi/proxy/plugin_resource_tracker.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/ppb_audio_proxy.h"
#include "ppapi/proxy/ppb_buffer_proxy.h"
#include "ppapi/proxy/ppb_broker_proxy.h"
#include "ppapi/proxy/ppb_context_3d_proxy.h"
#include "ppapi/proxy/ppb_file_chooser_proxy.h"
#include "ppapi/proxy/ppb_file_ref_proxy.h"
#include "ppapi/proxy/ppb_file_system_proxy.h"
#include "ppapi/proxy/ppb_flash_menu_proxy.h"
#include "ppapi/proxy/ppb_flash_net_connector_proxy.h"
#include "ppapi/proxy/ppb_flash_tcp_socket_proxy.h"
#include "ppapi/proxy/ppb_font_proxy.h"
#include "ppapi/proxy/ppb_graphics_2d_proxy.h"
#include "ppapi/proxy/ppb_graphics_3d_proxy.h"
#include "ppapi/proxy/ppb_image_data_proxy.h"
#include "ppapi/proxy/ppb_surface_3d_proxy.h"
#include "ppapi/proxy/ppb_url_loader_proxy.h"
#include "ppapi/proxy/ppb_video_capture_proxy.h"
#include "ppapi/proxy/ppb_video_decoder_proxy.h"
#include "ppapi/shared_impl/audio_config_impl.h"
#include "ppapi/shared_impl/font_impl.h"
#include "ppapi/shared_impl/function_group_base.h"
#include "ppapi/shared_impl/host_resource.h"
#include "ppapi/shared_impl/input_event_impl.h"
#include "ppapi/shared_impl/url_request_info_impl.h"
#include "ppapi/shared_impl/var.h"
#include "ppapi/thunk/enter.h"
#include "ppapi/thunk/ppb_image_data_api.h"
using ppapi::thunk::ResourceCreationAPI;
namespace ppapi {
namespace proxy {
ResourceCreationProxy::ResourceCreationProxy(Dispatcher* dispatcher)
: InterfaceProxy(dispatcher) {
}
ResourceCreationProxy::~ResourceCreationProxy() {
}
// static
InterfaceProxy* ResourceCreationProxy::Create(Dispatcher* dispatcher) {
return new ResourceCreationProxy(dispatcher);
}
ResourceCreationAPI* ResourceCreationProxy::AsResourceCreationAPI() {
return this;
}
PP_Resource ResourceCreationProxy::CreateAudio(
PP_Instance instance,
PP_Resource config_id,
PPB_Audio_Callback audio_callback,
void* user_data) {
return PPB_Audio_Proxy::CreateProxyResource(instance, config_id,
audio_callback, user_data);
}
PP_Resource ResourceCreationProxy::CreateAudioConfig(
PP_Instance instance,
PP_AudioSampleRate sample_rate,
uint32_t sample_frame_count) {
return AudioConfigImpl::CreateAsProxy(
instance, sample_rate, sample_frame_count);
}
PP_Resource ResourceCreationProxy::CreateAudioTrusted(PP_Instance instance) {
// Proxied plugins can't created trusted audio devices.
return 0;
}
PP_Resource ResourceCreationProxy::CreateBroker(PP_Instance instance) {
return PPB_Broker_Proxy::CreateProxyResource(instance);
}
PP_Resource ResourceCreationProxy::CreateBuffer(PP_Instance instance,
uint32_t size) {
return PPB_Buffer_Proxy::CreateProxyResource(instance, size);
}
PP_Resource ResourceCreationProxy::CreateContext3D(
PP_Instance instance,
PP_Config3D_Dev config,
PP_Resource share_context,
const int32_t* attrib_list) {
return PPB_Context3D_Proxy::Create(instance, config, share_context,
attrib_list);
}
PP_Resource ResourceCreationProxy::CreateContext3DRaw(
PP_Instance instance,
PP_Config3D_Dev config,
PP_Resource share_context,
const int32_t* attrib_list) {
// Not proxied. The raw creation function is used only in the implementation
// of the proxy on the host side.
return 0;
}
PP_Resource ResourceCreationProxy::CreateDirectoryReader(
PP_Resource directory_ref) {
NOTIMPLEMENTED(); // Not proxied yet.
return 0;
}
PP_Resource ResourceCreationProxy::CreateFileChooser(
PP_Instance instance,
PP_FileChooserMode_Dev mode,
const PP_Var& accept_mime_types) {
return PPB_FileChooser_Proxy::CreateProxyResource(instance, mode,
accept_mime_types);
}
PP_Resource ResourceCreationProxy::CreateFileIO(PP_Instance instance) {
NOTIMPLEMENTED(); // Not proxied yet.
return 0;
}
PP_Resource ResourceCreationProxy::CreateFileRef(PP_Resource file_system,
const char* path) {
return PPB_FileRef_Proxy::CreateProxyResource(file_system, path);
}
PP_Resource ResourceCreationProxy::CreateFileSystem(
PP_Instance instance,
PP_FileSystemType type) {
return PPB_FileSystem_Proxy::CreateProxyResource(instance, type);
}
PP_Resource ResourceCreationProxy::CreateFlashMenu(
PP_Instance instance,
const PP_Flash_Menu* menu_data) {
return PPB_Flash_Menu_Proxy::CreateProxyResource(instance, menu_data);
}
PP_Resource ResourceCreationProxy::CreateFlashNetConnector(
PP_Instance instance) {
return PPB_Flash_NetConnector_Proxy::CreateProxyResource(instance);
}
PP_Resource ResourceCreationProxy::CreateFlashTCPSocket(
PP_Instance instance) {
return PPB_Flash_TCPSocket_Proxy::CreateProxyResource(instance);
}
PP_Resource ResourceCreationProxy::CreateFontObject(
PP_Instance instance,
const PP_FontDescription_Dev* description) {
if (!ppapi::FontImpl::IsPPFontDescriptionValid(*description))
return 0;
return (new Font(HostResource::MakeInstanceOnly(instance), *description))->
GetReference();
}
PP_Resource ResourceCreationProxy::CreateGraphics2D(PP_Instance instance,
const PP_Size& size,
PP_Bool is_always_opaque) {
return PPB_Graphics2D_Proxy::CreateProxyResource(instance, size,
is_always_opaque);
}
PP_Resource ResourceCreationProxy::CreateImageData(PP_Instance instance,
PP_ImageDataFormat format,
const PP_Size& size,
PP_Bool init_to_zero) {
PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
if (!dispatcher)
return 0;
HostResource result;
std::string image_data_desc;
ImageHandle image_handle = ImageData::NullHandle;
dispatcher->Send(new PpapiHostMsg_ResourceCreation_ImageData(
INTERFACE_ID_RESOURCE_CREATION, instance, format, size, init_to_zero,
&result, &image_data_desc, &image_handle));
if (result.is_null() || image_data_desc.size() != sizeof(PP_ImageDataDesc))
return 0;
// We serialize the PP_ImageDataDesc just by copying to a string.
PP_ImageDataDesc desc;
memcpy(&desc, image_data_desc.data(), sizeof(PP_ImageDataDesc));
return (new ImageData(result, desc, image_handle))->GetReference();
}
PP_Resource ResourceCreationProxy::CreateKeyboardInputEvent(
PP_Instance instance,
PP_InputEvent_Type type,
PP_TimeTicks time_stamp,
uint32_t modifiers,
uint32_t key_code,
struct PP_Var character_text) {
if (type != PP_INPUTEVENT_TYPE_RAWKEYDOWN &&
type != PP_INPUTEVENT_TYPE_KEYDOWN &&
type != PP_INPUTEVENT_TYPE_KEYUP &&
type != PP_INPUTEVENT_TYPE_CHAR)
return 0;
ppapi::InputEventData data;
data.event_type = type;
data.event_time_stamp = time_stamp;
data.event_modifiers = modifiers;
data.key_code = key_code;
if (character_text.type == PP_VARTYPE_STRING) {
StringVar* text_str = StringVar::FromPPVar(character_text);
if (!text_str)
return 0;
data.character_text = text_str->value();
}
return (new InputEventImpl(InputEventImpl::InitAsProxy(),
instance, data))->GetReference();
}
PP_Resource ResourceCreationProxy::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,
const PP_Point* mouse_movement) {
if (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)
return 0;
ppapi::InputEventData data;
data.event_type = type;
data.event_time_stamp = time_stamp;
data.event_modifiers = modifiers;
data.mouse_button = mouse_button;
data.mouse_position = *mouse_position;
data.mouse_click_count = click_count;
data.mouse_movement = *mouse_movement;
return (new InputEventImpl(InputEventImpl::InitAsProxy(),
instance, data))->GetReference();
}
PP_Resource ResourceCreationProxy::CreateGraphics3D(
PP_Instance instance,
PP_Resource share_context,
const int32_t* attrib_list) {
return PPB_Graphics3D_Proxy::CreateProxyResource(
instance, share_context, attrib_list);
}
PP_Resource ResourceCreationProxy::CreateGraphics3DRaw(
PP_Instance instance,
PP_Resource share_context,
const int32_t* attrib_list) {
// Not proxied. The raw creation function is used only in the implementation
// of the proxy on the host side.
return 0;
}
PP_Resource ResourceCreationProxy::CreateScrollbar(PP_Instance instance,
PP_Bool vertical) {
NOTIMPLEMENTED(); // Not proxied yet.
return 0;
}
PP_Resource ResourceCreationProxy::CreateSurface3D(
PP_Instance instance,
PP_Config3D_Dev config,
const int32_t* attrib_list) {
return PPB_Surface3D_Proxy::CreateProxyResource(instance, config,
attrib_list);
}
PP_Resource ResourceCreationProxy::CreateTransport(PP_Instance instance,
const char* name,
PP_TransportType type) {
NOTIMPLEMENTED(); // Not proxied yet.
return 0;
}
PP_Resource ResourceCreationProxy::CreateURLLoader(PP_Instance instance) {
return PPB_URLLoader_Proxy::CreateProxyResource(instance);
}
PP_Resource ResourceCreationProxy::CreateURLRequestInfo(
PP_Instance instance,
const PPB_URLRequestInfo_Data& data) {
return (new URLRequestInfoImpl(
HostResource::MakeInstanceOnly(instance), data))->GetReference();
}
PP_Resource ResourceCreationProxy::CreateVideoCapture(PP_Instance instance) {
return PPB_VideoCapture_Proxy::CreateProxyResource(instance);
}
PP_Resource ResourceCreationProxy::CreateVideoDecoder(
PP_Instance instance,
PP_Resource context3d_id,
PP_VideoDecoder_Profile profile) {
return PPB_VideoDecoder_Proxy::CreateProxyResource(
instance, context3d_id, profile);
}
PP_Resource ResourceCreationProxy::CreateVideoLayer(
PP_Instance instance,
PP_VideoLayerMode_Dev mode) {
NOTIMPLEMENTED();
return 0;
}
PP_Resource ResourceCreationProxy::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) {
ppapi::InputEventData data;
data.event_type = PP_INPUTEVENT_TYPE_WHEEL;
data.event_time_stamp = time_stamp;
data.event_modifiers = modifiers;
data.wheel_delta = *wheel_delta;
data.wheel_ticks = *wheel_ticks;
data.wheel_scroll_by_page = PP_ToBool(scroll_by_page);
return (new InputEventImpl(InputEventImpl::InitAsProxy(),
instance, data))->GetReference();
}
bool ResourceCreationProxy::Send(IPC::Message* msg) {
return dispatcher()->Send(msg);
}
bool ResourceCreationProxy::OnMessageReceived(const IPC::Message& msg) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(ResourceCreationProxy, msg)
IPC_MESSAGE_HANDLER(PpapiHostMsg_ResourceCreation_Graphics2D,
OnMsgCreateGraphics2D)
IPC_MESSAGE_HANDLER(PpapiHostMsg_ResourceCreation_ImageData,
OnMsgCreateImageData)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void ResourceCreationProxy::OnMsgCreateGraphics2D(PP_Instance instance,
const PP_Size& size,
PP_Bool is_always_opaque,
HostResource* result) {
ppapi::thunk::EnterFunction<ResourceCreationAPI> enter(instance, false);
if (enter.succeeded()) {
result->SetHostResource(instance, enter.functions()->CreateGraphics2D(
instance, size, is_always_opaque));
}
}
void ResourceCreationProxy::OnMsgCreateImageData(
PP_Instance instance,
int32_t format,
const PP_Size& size,
PP_Bool init_to_zero,
HostResource* result,
std::string* image_data_desc,
ImageHandle* result_image_handle) {
*result_image_handle = ImageData::NullHandle;
ppapi::thunk::EnterFunction<ResourceCreationAPI> enter(instance, false);
if (enter.failed())
return;
PP_Resource resource = enter.functions()->CreateImageData(
instance, static_cast<PP_ImageDataFormat>(format), size, init_to_zero);
if (!resource)
return;
result->SetHostResource(instance, resource);
// Get the description, it's just serialized as a string.
ppapi::thunk::EnterResourceNoLock<ppapi::thunk::PPB_ImageData_API>
enter_resource(resource, false);
PP_ImageDataDesc desc;
if (enter_resource.object()->Describe(&desc) == PP_TRUE) {
image_data_desc->resize(sizeof(PP_ImageDataDesc));
memcpy(&(*image_data_desc)[0], &desc, sizeof(PP_ImageDataDesc));
}
// Get the shared memory handle.
const PPB_ImageDataTrusted* trusted =
reinterpret_cast<const PPB_ImageDataTrusted*>(
dispatcher()->local_get_interface()(PPB_IMAGEDATA_TRUSTED_INTERFACE));
uint32_t byte_count = 0;
if (trusted) {
int32_t handle;
if (trusted->GetSharedMemory(resource, &handle, &byte_count) == PP_OK) {
#if defined(OS_WIN)
ImageHandle ih = ImageData::HandleFromInt(handle);
*result_image_handle = dispatcher()->ShareHandleWithRemote(ih, false);
#else
*result_image_handle = ImageData::HandleFromInt(handle);
#endif
}
}
}
} // namespace proxy
} // namespace ppapi