Chromium Code Reviews| Index: ppapi/proxy/ppb_broker_proxy.cc |
| diff --git a/ppapi/proxy/ppb_broker_proxy.cc b/ppapi/proxy/ppb_broker_proxy.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..83539cea1613f9a3db494339162fcb9b8de580ea |
| --- /dev/null |
| +++ b/ppapi/proxy/ppb_broker_proxy.cc |
| @@ -0,0 +1,206 @@ |
| +// 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/ppb_broker_proxy.h" |
| + |
| +#include "ppapi/c/pp_errors.h" |
| +#include "ppapi/c/trusted/ppb_broker_trusted.h" |
| +#include "ppapi/proxy/plugin_dispatcher.h" |
| +#include "ppapi/proxy/plugin_resource.h" |
| +#include "ppapi/proxy/ppapi_messages.h" |
| + |
| +namespace pp { |
| +namespace proxy { |
| + |
| +class Broker : public PluginResource { |
| + public: |
| + explicit Broker(const HostResource& resource); |
| + |
| + // Resource overrides. |
| + virtual Broker* AsBroker() { return this; } |
| + |
| + int32_t Connect(PP_Resource broker, PP_CompletionCallback connect_callback); |
| + int32_t GetHandle(PP_Resource broker, int32_t* handle); |
| + |
| + private: |
| + DISALLOW_COPY_AND_ASSIGN(Broker); |
| +}; |
| + |
| +Broker::Broker(const HostResource& resource) |
| + : PluginResource(resource) { |
| +} |
| + |
| +int32_t Broker::Connect(PP_Resource broker, |
| + PP_CompletionCallback connect_callback) { |
| + PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance()); |
| + if (!dispatcher) |
| + return PP_ERROR_BADRESOURCE; |
| + if (!connect_callback.func) { |
| + // Synchronous calls are not supported. |
| + return PP_ERROR_BADARGUMENT; |
| + } |
| + |
| + bool success = dispatcher->Send(new PpapiHostMsg_PPBBroker_Connect( |
| + INTERFACE_ID_PPB_BROKER, |
| + host_resource(), |
| + dispatcher->callback_tracker().SendCallback(connect_callback))); |
| + return success ? PP_ERROR_WOULDBLOCK : PP_ERROR_FAILED; |
| +} |
| + |
| +// Assumes the IPC does not populate the ipc_handle unless result is S_OK. |
| +// TODO(ddorwin): Depending on how what is decided regarding ownership, |
| +// it may make sense to cache the handle here. |
|
brettw
2011/04/13 17:53:40
I think we should have the Broker object manage th
ddorwin
2011/04/14 18:08:38
Done.
I also updated several comments about handl
|
| +int32_t Broker::GetHandle(PP_Resource broker, int32_t* handle) { |
| + PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance()); |
| + if (!dispatcher) |
| + return PP_ERROR_BADRESOURCE; |
| + |
| + IPC::PlatformFileForTransit ipc_handle = IPC::InvalidPlatformFileForTransit(); |
| + int32_t result = PP_ERROR_FAILED; |
| + bool success = dispatcher->Send(new PpapiHostMsg_PPBBroker_GetHandle( |
| + INTERFACE_ID_PPB_BROKER, |
| + host_resource(), |
| + &ipc_handle, |
| + &result)); |
| + if (!success) |
| + return PP_ERROR_FAILED; |
| + if (result != PP_OK) |
| + return result; |
| + |
| + base::SyncSocket::Handle socket_handle = |
| + IPC::PlatformFileForTransitToPlatformFile(ipc_handle); |
| + *handle = socket_handle; |
| + return result; |
| +} |
| + |
| +namespace { |
| + |
| +PP_Resource CreateTrusted(PP_Instance instance) { |
| + PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); |
| + if (!dispatcher) |
| + return 0; |
| + |
| + HostResource result; |
| + dispatcher->Send(new PpapiHostMsg_PPBBroker_Create( |
| + INTERFACE_ID_PPB_BROKER, instance, &result)); |
| + if (result.is_null()) |
| + return 0; |
| + |
| + linked_ptr<Broker> object(new Broker(result)); |
| + return PluginResourceTracker::GetInstance()->AddResource(object); |
| +} |
| + |
| +PP_Bool IsBrokerTrusted(PP_Resource resource) { |
| + Broker* object = PluginResource::GetAs<Broker>(resource); |
| + return BoolToPPBool(!!object); |
| +} |
| + |
| +int32_t Connect(PP_Resource resource, |
| + PP_CompletionCallback connect_callback) { |
| + Broker* object = PluginResource::GetAs<Broker>(resource); |
| + if (!object) |
| + return PP_ERROR_BADRESOURCE; |
| + return object->Connect(resource, connect_callback); |
| +} |
| + |
| +int32_t GetHandle(PP_Resource resource, int32_t* handle) { |
| + Broker* object = PluginResource::GetAs<Broker>(resource); |
| + if (!object) |
| + return PP_ERROR_BADRESOURCE; |
| + return object->GetHandle(resource, handle); |
| +} |
| + |
| +const PPB_BrokerTrusted broker_interface = { |
| + &CreateTrusted, |
| + &IsBrokerTrusted, |
| + &Connect, |
| + &GetHandle, |
| +}; |
| + |
| +InterfaceProxy* CreateBrokerProxy(Dispatcher* dispatcher, |
| + const void* target_interface) { |
| + return new PPB_Broker_Proxy(dispatcher, target_interface); |
| +} |
| + |
| +base::PlatformFile IntToPlatformFile(int32_t handle) { |
| +#if defined(OS_WIN) |
| + return reinterpret_cast<HANDLE>(static_cast<intptr_t>(handle)); |
| +#elif defined(OS_POSIX) |
| + return handle; |
| +#else |
| + #error Not implemented. |
| +#endif |
| +} |
| + |
| +} // namespace |
| + |
| +PPB_Broker_Proxy::PPB_Broker_Proxy(Dispatcher* dispatcher, |
| + const void* target_interface) |
| + : InterfaceProxy(dispatcher, target_interface) { |
| +} |
| + |
| +PPB_Broker_Proxy::~PPB_Broker_Proxy() { |
| +} |
| + |
| +// static |
| +const InterfaceProxy::Info* PPB_Broker_Proxy::GetInfo() { |
| + static const Info info = { |
| + &broker_interface, |
| + PPB_BROKER_TRUSTED_INTERFACE, |
| + INTERFACE_ID_PPB_BROKER, |
| + false, |
|
brettw
2011/04/13 17:53:40
This should be true for is_trusted.
ddorwin
2011/04/14 18:08:38
Done.
|
| + &CreateBrokerProxy, |
| + }; |
| + return &info; |
| +} |
| + |
| +bool PPB_Broker_Proxy::OnMessageReceived(const IPC::Message& msg) { |
| + bool handled = true; |
| + IPC_BEGIN_MESSAGE_MAP(PPB_Broker_Proxy, msg) |
| + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBBroker_Create, OnMsgCreate) |
| + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBBroker_Connect, OnMsgConnect) |
| + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBBroker_GetHandle, OnMsgGetHandle) |
| + IPC_MESSAGE_UNHANDLED(handled = false) |
| + IPC_END_MESSAGE_MAP() |
| + return handled; |
| +} |
| + |
| +void PPB_Broker_Proxy::OnMsgCreate(PP_Instance instance, |
| + HostResource* result_resource) { |
| + result_resource->SetHostResource( |
| + instance, |
| + ppb_broker_target()->CreateTrusted(instance)); |
| +} |
| + |
| +void PPB_Broker_Proxy::OnMsgConnect(const HostResource& broker, |
| + uint32_t serialized_callback) { |
| + PP_CompletionCallback callback = ReceiveCallback(serialized_callback); |
| + int32_t result = ppb_broker_target()->Connect(broker.host_resource(), |
| + callback); |
| + if (result != PP_ERROR_WOULDBLOCK) |
| + PP_RunCompletionCallback(&callback, result); |
| +} |
| + |
| +void PPB_Broker_Proxy::OnMsgGetHandle( |
| + const HostResource& broker, |
| + IPC::PlatformFileForTransit* foreign_socket_handle, |
| + int32_t* result) { |
| + DCHECK(foreign_socket_handle); |
| + DCHECK(result); |
| + |
| + int32_t socket_handle = 0; |
| + *result = ppb_broker_target()->GetHandle(broker.host_resource(), |
| + &socket_handle); |
| + if (*result != PP_OK) |
| + return; |
| + |
| + // socket_handle doesn't belong to us: don't close it. |
| + *foreign_socket_handle = dispatcher()->ShareHandleWithRemote( |
| + IntToPlatformFile(socket_handle), false); |
| + if (*foreign_socket_handle == IPC::InvalidPlatformFileForTransit()) |
| + *result = PP_ERROR_FAILED; |
| +} |
| + |
| +} // namespace proxy |
| +} // namespace pp |