diff options
70 files changed, 1253 insertions, 638 deletions
diff --git a/chrome/ppapi_plugin/ppapi_thread.cc b/chrome/ppapi_plugin/ppapi_thread.cc index 0fc5ace..4e8c0c9 100644 --- a/chrome/ppapi_plugin/ppapi_thread.cc +++ b/chrome/ppapi_plugin/ppapi_thread.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -25,7 +25,6 @@ PpapiThread::PpapiThread() } PpapiThread::~PpapiThread() { - pp::proxy::PluginDispatcher::SetGlobal(NULL); } // The "regular" ChildThread implements this function and does some standard @@ -38,12 +37,6 @@ PpapiThread::~PpapiThread() { bool PpapiThread::OnMessageReceived(const IPC::Message& msg) { IPC_BEGIN_MESSAGE_MAP(PpapiThread, msg) IPC_MESSAGE_HANDLER(PpapiMsg_LoadPlugin, OnMsgLoadPlugin) - - // The rest of the messages go to the dispatcher. - /*IPC_MESSAGE_UNHANDLED( - if (dispatcher_.get()) - dispatcher_->OnMessageReceived(msg) - )*/ IPC_END_MESSAGE_MAP() return true; } @@ -94,7 +87,6 @@ bool PpapiThread::LoadPluginLib(base::ProcessHandle host_process_handle, library_.Reset(library.Release()); dispatcher_.reset(new pp::proxy::PluginDispatcher( host_process_handle, get_interface, init_module, shutdown_module)); - pp::proxy::PluginDispatcher::SetGlobal(dispatcher_.get()); return true; } diff --git a/ipc/ipc_test_sink.h b/ipc/ipc_test_sink.h index d0895aa..bac8943 100644 --- a/ipc/ipc_test_sink.h +++ b/ipc/ipc_test_sink.h @@ -42,6 +42,13 @@ class Message; // // Go on to the next phase of the test. // test_sink.ClearMessages(); // +// To read a sync reply, do this: +// +// IPC::Message* msg = test_sink.GetUniqueMessageMatching(IPC_REPLY_ID); +// ASSERT_TRUE(msg); +// TupleTypes<ViewHostMsg_Foo::ReplyParam>::ValueType reply_data; +// EXPECT_TRUE(ViewHostMsg_Foo::ReadReplyParam(msg, &reply_data)); +// // You can also register to be notified when messages are posted to the sink. // This can be useful if you need to wait for a particular message that will // be posted asynchronously. Example usage: diff --git a/ppapi/c/dev/ppb_opengles_dev.h b/ppapi/c/dev/ppb_opengles_dev.h index 254a313..a4caa84 100644 --- a/ppapi/c/dev/ppb_opengles_dev.h +++ b/ppapi/c/dev/ppb_opengles_dev.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. diff --git a/ppapi/ppapi_tests.gypi b/ppapi/ppapi_tests.gypi index 9734827..0611734 100644 --- a/ppapi/ppapi_tests.gypi +++ b/ppapi/ppapi_tests.gypi @@ -267,8 +267,10 @@ 'sources': [ 'proxy/run_all_unittests.cc', + 'proxy/host_dispatcher_unittest.cc', 'proxy/mock_resource.cc', 'proxy/mock_resource.h', + 'proxy/plugin_dispatcher_unittest.cc', 'proxy/plugin_resource_tracker_unittest.cc', 'proxy/plugin_var_tracker_unittest.cc', 'proxy/ppapi_proxy_test.cc', diff --git a/ppapi/proxy/dispatcher.cc b/ppapi/proxy/dispatcher.cc index 9ad6aca..eb9726b 100644 --- a/ppapi/proxy/dispatcher.cc +++ b/ppapi/proxy/dispatcher.cc @@ -10,6 +10,7 @@ #include "base/compiler_specific.h" #include "base/logging.h" +#include "base/singleton.h" #include "ipc/ipc_message.h" #include "ipc/ipc_sync_channel.h" #include "ipc/ipc_test_sink.h" @@ -68,6 +69,86 @@ namespace pp { namespace proxy { +namespace { + +struct InterfaceList { + InterfaceList(); + + static InterfaceList* GetInstance(); + + void AddPPP(const InterfaceProxy::Info* info); + void AddPPB(const InterfaceProxy::Info* info); + + typedef std::map<std::string, const InterfaceProxy::Info*> NameToInfo; + NameToInfo name_to_plugin_info_; + NameToInfo name_to_browser_info_; + + const InterfaceProxy::Info* id_to_plugin_info_[INTERFACE_ID_COUNT]; + const InterfaceProxy::Info* id_to_browser_info_[INTERFACE_ID_COUNT]; +}; + +InterfaceList::InterfaceList() { + memset(id_to_plugin_info_, 0, + static_cast<int>(INTERFACE_ID_COUNT) * sizeof(InterfaceID)); + memset(id_to_browser_info_, 0, + static_cast<int>(INTERFACE_ID_COUNT) * sizeof(InterfaceID)); + + // PPB (browser) interfaces. + AddPPB(PPB_AudioConfig_Proxy::GetInfo()); + AddPPB(PPB_Audio_Proxy::GetInfo()); + AddPPB(PPB_Buffer_Proxy::GetInfo()); + AddPPB(PPB_CharSet_Proxy::GetInfo()); + AddPPB(PPB_Context3D_Proxy::GetInfo()); + AddPPB(PPB_Core_Proxy::GetInfo()); + AddPPB(PPB_CursorControl_Proxy::GetInfo()); + AddPPB(PPB_Flash_Proxy::GetInfo()); + AddPPB(PPB_Font_Proxy::GetInfo()); + AddPPB(PPB_Fullscreen_Proxy::GetInfo()); + AddPPB(PPB_GLESChromiumTextureMapping_Proxy::GetInfo()); + AddPPB(PPB_Graphics2D_Proxy::GetInfo()); + AddPPB(PPB_ImageData_Proxy::GetInfo()); + AddPPB(PPB_Instance_Proxy::GetInfo()); + AddPPB(PPB_OpenGLES2_Proxy::GetInfo()); + AddPPB(PPB_PDF_Proxy::GetInfo()); + AddPPB(PPB_Surface3D_Proxy::GetInfo()); + AddPPB(PPB_Testing_Proxy::GetInfo()); + AddPPB(PPB_URLLoader_Proxy::GetInfo()); + AddPPB(PPB_URLLoaderTrusted_Proxy::GetInfo()); + AddPPB(PPB_URLRequestInfo_Proxy::GetInfo()); + AddPPB(PPB_URLResponseInfo_Proxy::GetInfo()); + AddPPB(PPB_Var_Deprecated_Proxy::GetInfo()); + + // PPP (plugin) interfaces. + AddPPP(PPP_Instance_Proxy::GetInfo()); +} + +void InterfaceList::AddPPP(const InterfaceProxy::Info* info) { + DCHECK(name_to_plugin_info_.find(info->name) == + name_to_plugin_info_.end()); + DCHECK(info->id > 0 && info->id < INTERFACE_ID_COUNT); + DCHECK(id_to_plugin_info_[info->id] == NULL); + + name_to_plugin_info_[info->name] = info; + id_to_plugin_info_[info->id] = info; +} + +void InterfaceList::AddPPB(const InterfaceProxy::Info* info) { + DCHECK(name_to_browser_info_.find(info->name) == + name_to_browser_info_.end()); + DCHECK(info->id > 0 && info->id < INTERFACE_ID_COUNT); + DCHECK(id_to_browser_info_[info->id] == NULL); + + name_to_browser_info_[std::string(info->name)] = info; + id_to_browser_info_[info->id] = info; +} + +// static +InterfaceList* InterfaceList::GetInstance() { + return Singleton<InterfaceList>::get(); +} + +} // namespace + Dispatcher::Dispatcher(base::ProcessHandle remote_process_handle, GetInterfaceFunc local_get_interface) : pp_module_(0), @@ -75,10 +156,7 @@ Dispatcher::Dispatcher(base::ProcessHandle remote_process_handle, test_sink_(NULL), disallow_trusted_interfaces_(false), // TODO(brettw) make this settable. local_get_interface_(local_get_interface), - declared_supported_remote_interfaces_(false), callback_tracker_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { - memset(id_to_proxy_, 0, - static_cast<int>(INTERFACE_ID_COUNT) * sizeof(InterfaceProxy*)); } Dispatcher::~Dispatcher() { @@ -105,70 +183,60 @@ bool Dispatcher::OnMessageReceived(const IPC::Message& msg) { if (msg.routing_id() == MSG_ROUTING_CONTROL) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(Dispatcher, msg) - IPC_MESSAGE_HANDLER(PpapiMsg_DeclareInterfaces, - OnMsgDeclareInterfaces) - IPC_MESSAGE_HANDLER(PpapiMsg_SupportsInterface, OnMsgSupportsInterface) IPC_MESSAGE_FORWARD(PpapiMsg_ExecuteCallback, &callback_tracker_, CallbackTracker::ReceiveExecuteSerializedCallback) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; } - - // Interface-specific messages. - if (msg.routing_id() > 0 && msg.routing_id() < INTERFACE_ID_COUNT) { - InterfaceProxy* proxy = id_to_proxy_[msg.routing_id()]; - if (proxy) - return proxy->OnMessageReceived(msg); - - NOTREACHED(); - // TODO(brettw): kill the plugin if it starts sending invalid messages? - } - return false; } -void Dispatcher::SetSerializationRules( - VarSerializationRules* var_serialization_rules) { - serialization_rules_.reset(var_serialization_rules); -} - -void Dispatcher::InjectProxy(InterfaceID id, - const std::string& name, - InterfaceProxy* proxy) { - proxies_[name] = linked_ptr<InterfaceProxy>(proxy); - id_to_proxy_[id] = proxy; +// static +const InterfaceProxy::Info* Dispatcher::GetPPBInterfaceInfo( + const std::string& name) { + const InterfaceList* list = InterfaceList::GetInstance(); + InterfaceList::NameToInfo::const_iterator found = + list->name_to_browser_info_.find(name); + if (found == list->name_to_browser_info_.end()) + return NULL; + return found->second; } -const void* Dispatcher::GetLocalInterface(const char* interface) { - return local_get_interface_(interface); +// static +const InterfaceProxy::Info* Dispatcher::GetPPBInterfaceInfo(InterfaceID id) { + if (id <= 0 || id >= INTERFACE_ID_COUNT) + return NULL; + const InterfaceList* list = InterfaceList::GetInstance(); + return list->id_to_browser_info_[id]; } -const void* Dispatcher::GetProxiedInterface(const std::string& interface) { - // See if we already know about this interface and have created a host. - ProxyMap::const_iterator found = proxies_.find(interface); - if (found != proxies_.end()) - return found->second->GetSourceInterface(); - - // When the remote side has sent us a declared list of all interfaces it - // supports and we don't have it in our list, we know the requested interface - // doesn't exist and we can return failure. - if (declared_supported_remote_interfaces_) +// static +const InterfaceProxy::Info* Dispatcher::GetPPPInterfaceInfo( + const std::string& name) { + const InterfaceList* list = InterfaceList::GetInstance(); + InterfaceList::NameToInfo::const_iterator found = + list->name_to_plugin_info_.find(name); + if (found == list->name_to_plugin_info_.end()) return NULL; + return found->second; +} - if (!RemoteSupportsTargetInterface(interface)) +// static +const InterfaceProxy::Info* Dispatcher::GetPPPInterfaceInfo(InterfaceID id) { + if (id <= 0 || id >= INTERFACE_ID_COUNT) return NULL; + const InterfaceList* list = InterfaceList::GetInstance(); + return list->id_to_plugin_info_[id]; +} - linked_ptr<InterfaceProxy> proxy(CreateProxyForInterface(interface, NULL)); - if (!proxy.get()) - return NULL; // Don't know how to proxy this interface. +void Dispatcher::SetSerializationRules( + VarSerializationRules* var_serialization_rules) { + serialization_rules_.reset(var_serialization_rules); +} - // Save our proxy. - proxies_[interface] = proxy; - InterfaceID id = proxy->GetInterfaceId(); - if (id != INTERFACE_ID_NONE) - id_to_proxy_[id] = proxy.get(); - return proxy->GetSourceInterface(); +const void* Dispatcher::GetLocalInterface(const char* interface) { + return local_get_interface_(interface); } bool Dispatcher::Send(IPC::Message* msg) { @@ -177,131 +245,6 @@ bool Dispatcher::Send(IPC::Message* msg) { return channel_->Send(msg); } -bool Dispatcher::RemoteSupportsTargetInterface(const std::string& interface) { - bool result = false; - Send(new PpapiMsg_SupportsInterface(interface, &result)); - return result; -} - -bool Dispatcher::IsInterfaceTrusted(const std::string& interface) { - // FIXME(brettw) - (void)interface; - return false; -} - -bool Dispatcher::SetupProxyForTargetInterface(const std::string& interface) { - // If we already have a proxy that knows about the locally-implemented - // interface, we know it's supported and don't need to re-query. - ProxyMap::const_iterator found = proxies_.find(interface); - if (found != proxies_.end()) - return true; - - if (disallow_trusted_interfaces_ && IsInterfaceTrusted(interface)) - return false; - - // Create the proxy if it doesn't exist and set the local interface on it. - // This also handles the case where possibly an interface could be supported - // by both the local and remote side. - const void* interface_functions = local_get_interface_(interface.c_str()); - if (!interface_functions) - return false; - InterfaceProxy* proxy = CreateProxyForInterface(interface, - interface_functions); - if (!proxy) - return false; - - proxies_[interface] = linked_ptr<InterfaceProxy>(proxy); - id_to_proxy_[proxy->GetInterfaceId()] = proxy; - return true; -} - -void Dispatcher::OnMsgSupportsInterface(const std::string& interface_name, - bool* result) { - *result = SetupProxyForTargetInterface(interface_name); -} - -void Dispatcher::OnMsgDeclareInterfaces( - const std::vector<std::string>& interfaces) { - // Make proxies for all the interfaces it supports that we also support. - for (size_t i = 0; i < interfaces.size(); i++) { - // Possibly the plugin could request an interface before the "declare" - // message is received, so we could already have an entry for this - // interface. In this case, we can just skip to the next one. - if (proxies_.find(interfaces[i]) != proxies_.end()) - continue; - - linked_ptr<InterfaceProxy> proxy(CreateProxyForInterface(interfaces[i], - NULL)); - if (!proxy.get()) { - // Since only the browser declares supported interfaces, we should never - // get one we don't support. - //NOTREACHED() << "Remote side declaring an unsupported proxy."; - continue; - } - proxies_[interfaces[i]] = proxy; - id_to_proxy_[proxy->GetInterfaceId()] = proxy.get(); - } -} - -InterfaceProxy* Dispatcher::CreateProxyForInterface( - const std::string& interface_name, - const void* interface_functions) { - if (interface_name == PPB_AUDIO_CONFIG_INTERFACE) - return new PPB_AudioConfig_Proxy(this, interface_functions); - if (interface_name == PPB_AUDIO_INTERFACE) - return new PPB_Audio_Proxy(this, interface_functions); - if (interface_name == PPB_BUFFER_DEV_INTERFACE) - return new PPB_Buffer_Proxy(this, interface_functions); - if (interface_name == PPB_CHAR_SET_DEV_INTERFACE) - return new PPB_CharSet_Proxy(this, interface_functions); - if (interface_name == PPB_CONTEXT_3D_DEV_INTERFACE) - return new PPB_Context3D_Proxy(this, interface_functions); - if (interface_name == PPB_CORE_INTERFACE) - return new PPB_Core_Proxy(this, interface_functions); - if (interface_name == PPB_CURSOR_CONTROL_DEV_INTERFACE) - return new PPB_CursorControl_Proxy(this, interface_functions); - if (interface_name == PPB_FONT_DEV_INTERFACE) - return new PPB_Font_Proxy(this, interface_functions); - if (interface_name == PPB_FULLSCREEN_DEV_INTERFACE) - return new PPB_Fullscreen_Proxy(this, interface_functions); - if (interface_name == PPB_GLES_CHROMIUM_TEXTURE_MAPPING_DEV_INTERFACE) - return new PPB_GLESChromiumTextureMapping_Proxy(this, interface_functions); - if (interface_name == PPB_GRAPHICS_2D_INTERFACE) - return new PPB_Graphics2D_Proxy(this, interface_functions); - if (interface_name == PPB_IMAGEDATA_INTERFACE) - return new PPB_ImageData_Proxy(this, interface_functions); - if (interface_name == PPB_INSTANCE_INTERFACE) - return new PPB_Instance_Proxy(this, interface_functions); - if (interface_name == PPB_OPENGLES2_DEV_INTERFACE) - return new PPB_OpenGLES2_Proxy(this, interface_functions); - if (interface_name == PPB_SURFACE_3D_DEV_INTERFACE) - return new PPB_Surface3D_Proxy(this, interface_functions); - if (interface_name == PPB_TESTING_DEV_INTERFACE) - return new PPB_Testing_Proxy(this, interface_functions); - if (interface_name == PPB_URLLOADER_INTERFACE) - return new PPB_URLLoader_Proxy(this, interface_functions); - if (interface_name == PPB_URLREQUESTINFO_INTERFACE) - return new PPB_URLRequestInfo_Proxy(this, interface_functions); - if (interface_name == PPB_URLRESPONSEINFO_INTERFACE) - return new PPB_URLResponseInfo_Proxy(this, interface_functions); - if (interface_name == PPB_VAR_DEPRECATED_INTERFACE) - return new PPB_Var_Deprecated_Proxy(this, interface_functions); - if (interface_name == PPP_INSTANCE_INTERFACE) - return new PPP_Instance_Proxy(this, interface_functions); - - // Trusted interfaces. - if (!disallow_trusted_interfaces_) { - if (interface_name == PPB_FLASH_INTERFACE) - return new PPB_Flash_Proxy(this, interface_functions); - if (interface_name == PPB_PDF_INTERFACE) - return new PPB_PDF_Proxy(this, interface_functions); - if (interface_name == PPB_URLLOADERTRUSTED_INTERFACE) - return new PPB_URLLoaderTrusted_Proxy(this, interface_functions); - } - - return NULL; -} - } // namespace proxy } // namespace pp diff --git a/ppapi/proxy/dispatcher.h b/ppapi/proxy/dispatcher.h index 1aac12d..b3b520d 100644 --- a/ppapi/proxy/dispatcher.h +++ b/ppapi/proxy/dispatcher.h @@ -18,6 +18,7 @@ #include "ppapi/c/pp_module.h" #include "ppapi/proxy/callback_tracker.h" #include "ppapi/proxy/interface_id.h" +#include "ppapi/proxy/interface_proxy.h" #include "ppapi/proxy/plugin_var_tracker.h" class MessageLoop; @@ -35,7 +36,6 @@ class TestSink; namespace pp { namespace proxy { -class InterfaceProxy; class VarSerializationRules; // An interface proxy can represent either end of a cross-process interface @@ -86,13 +86,6 @@ class Dispatcher : public IPC::Channel::Listener, // Wrapper for calling the local GetInterface function. const void* GetLocalInterface(const char* interface); - // Implements PPP_GetInterface and PPB_GetInterface on the "source" side. It - // will check if the remote side supports this interface as a target, and - // create a proxy if it does. A local implementation of that interface backed - // by the proxy will be returned on success. If the interface is unproxyable - // or not supported by the remote side, returns NULL. - const void* GetProxiedInterface(const std::string& interface); - // Returns the remote process' handle. For the host dispatcher, this will be // the plugin process, and for the plugin dispatcher, this will be the // renderer process. This is used for sharing memory and such and is @@ -120,6 +113,17 @@ class Dispatcher : public IPC::Channel::Listener, return callback_tracker_; } + // Retrieves the information associated with the given interface, identified + // either by name or ID. Each function searches either PPP or PPB interfaces. + static const InterfaceProxy::Info* GetPPBInterfaceInfo( + const std::string& name); + static const InterfaceProxy::Info* GetPPBInterfaceInfo( + InterfaceID id); + static const InterfaceProxy::Info* GetPPPInterfaceInfo( + const std::string& name); + static const InterfaceProxy::Info* GetPPPInterfaceInfo( + InterfaceID id); + protected: Dispatcher(base::ProcessHandle remote_process_handle, GetInterfaceFunc local_get_interface); @@ -132,41 +136,11 @@ class Dispatcher : public IPC::Channel::Listener, pp_module_ = module; } - // Allows the PluginDispatcher to add a magic proxy for PPP_Class, bypassing - // the normal "do you support this proxy" stuff and the big lookup of - // name to proxy object. Takes ownership of the pointer. - void InjectProxy(InterfaceID id, - const std::string& name, - InterfaceProxy* proxy); + bool disallow_trusted_interfaces() const { + return disallow_trusted_interfaces_; + } private: - typedef std::map< std::string, linked_ptr<InterfaceProxy> > ProxyMap; - - // Message handlers - void OnMsgSupportsInterface(const std::string& interface_name, bool* result); - void OnMsgDeclareInterfaces(const std::vector<std::string>& interfaces); - - // Allocates a new proxy on the heap corresponding to the given interface - // name, or returns NULL if that interface name isn't known proxyable. The - // caller owns the returned pointer. - // - // The interface_functions gives the pointer to the local interfece when this - // is a target proxy. When creating a source proxy, set this to NULL. - InterfaceProxy* CreateProxyForInterface( - const std::string& interface_name, - const void* interface_functions); - - // Returns true if the remote side supports the given interface as the - // target of an IPC call. - bool RemoteSupportsTargetInterface(const std::string& interface); - - // Sets up a proxy as the target for the given interface, if it is supported. - // Returns true if this process implements the given interface and it is - // proxyable. - bool SetupProxyForTargetInterface(const std::string& interface); - - bool IsInterfaceTrusted(const std::string& interface); - // Set by the derived classed to indicate the module ID corresponding to // this dispatcher. PP_Module pp_module_; @@ -185,20 +159,6 @@ class Dispatcher : public IPC::Channel::Listener, GetInterfaceFunc local_get_interface_; - ProxyMap proxies_; - InterfaceProxy* id_to_proxy_[INTERFACE_ID_COUNT]; - - // True if the remote side has declared which interfaces it supports in - // advance. When set, it means if we don't already have a source proxy for - // the requested interface, that the remote side doesn't support it and - // we don't need to query. - // - // This is just an optimization. The browser has a fixed set of interfaces - // it supports, and the many plugins will end up querying many of them. By - // having the browser just send all of those interfaces in one message, we - // can avoid a bunch of IPC chatter to set up each interface. - bool declared_supported_remote_interfaces_; - CallbackTracker callback_tracker_; scoped_ptr<VarSerializationRules> serialization_rules_; diff --git a/ppapi/proxy/host_dispatcher.cc b/ppapi/proxy/host_dispatcher.cc index c196c14..7978786 100644 --- a/ppapi/proxy/host_dispatcher.cc +++ b/ppapi/proxy/host_dispatcher.cc @@ -30,6 +30,9 @@ HostDispatcher::HostDispatcher(base::ProcessHandle remote_process_handle, static_cast<const PPB_Var_Deprecated*>( local_get_interface(PPB_VAR_DEPRECATED_INTERFACE)); SetSerializationRules(new HostVarSerializationRules(var_interface, module)); + + memset(plugin_interface_support_, 0, + sizeof(PluginInterfaceSupport) * INTERFACE_ID_COUNT); } HostDispatcher::~HostDispatcher() { @@ -76,6 +79,68 @@ bool HostDispatcher::IsPlugin() const { return false; } +bool HostDispatcher::OnMessageReceived(const IPC::Message& msg) { + // Handle common control messages. + if (Dispatcher::OnMessageReceived(msg)) + return true; + + if (msg.routing_id() <= 0 && msg.routing_id() >= INTERFACE_ID_COUNT) { + NOTREACHED(); + // TODO(brettw): kill the plugin if it starts sending invalid messages? + return true; + } + + InterfaceProxy* proxy = target_proxies_[msg.routing_id()].get(); + if (!proxy) { + // Autocreate any proxy objects to handle requests from the plugin. Since + // we always support all known PPB_* interfaces (modulo the trusted bit), + // there's very little checking necessary. + const InterfaceProxy::Info* info = GetPPBInterfaceInfo( + static_cast<InterfaceID>(msg.routing_id())); + if (!info || + (info->is_trusted && disallow_trusted_interfaces())) + return true; + + const void* local_interface = GetLocalInterface(info->name); + if (!local_interface) { + // This should always succeed since the browser should support the stuff + // the proxy does. If this happens, something is out of sync. + NOTREACHED(); + return true; + } + + proxy = info->create_proxy(this, local_interface); + target_proxies_[info->id].reset(proxy); + } + + return proxy->OnMessageReceived(msg); +} + +const void* HostDispatcher::GetProxiedInterface(const std::string& interface) { + // First see if we even have a proxy for this interface. + const InterfaceProxy::Info* info = GetPPPInterfaceInfo(interface); + if (!info) + return NULL; + + if (plugin_interface_support_[static_cast<int>(info->id)] != + INTERFACE_UNQUERIED) { + // Already queried the plugin if it supports this interface. + if (plugin_interface_support_[info->id] == INTERFACE_SUPPORTED) + return info->interface; + return NULL; + } + + // Need to re-query. Cache the result so we only do this once. + bool supported = false; + Send(new PpapiMsg_SupportsInterface(interface, &supported)); + plugin_interface_support_[static_cast<int>(info->id)] = + supported ? INTERFACE_SUPPORTED : INTERFACE_UNSUPPORTED; + + if (supported) + return info->interface; + return NULL; +} + } // namespace proxy } // namespace pp diff --git a/ppapi/proxy/host_dispatcher.h b/ppapi/proxy/host_dispatcher.h index 2112405..f405f71 100644 --- a/ppapi/proxy/host_dispatcher.h +++ b/ppapi/proxy/host_dispatcher.h @@ -41,10 +41,6 @@ class HostDispatcher : public Dispatcher { GetInterfaceFunc local_get_interface); ~HostDispatcher(); - // Calls the plugin's PPP_InitializeModule function and returns true if - // the call succeeded. - bool InitializeModule(); - // The host side maintains a mapping from PP_Instance to Dispatcher so // that we can send the messages to the right channel. static HostDispatcher* GetForInstance(PP_Instance instance); @@ -52,10 +48,36 @@ class HostDispatcher : public Dispatcher { HostDispatcher* dispatcher); static void RemoveForInstance(PP_Instance instance); + // Calls the plugin's PPP_InitializeModule function and returns true if + // the call succeeded. + bool InitializeModule(); + // Dispatcher overrides. virtual bool IsPlugin() const; + // IPC::Channel::Listener. + virtual bool OnMessageReceived(const IPC::Message& msg); + + // Proxied version of calling GetInterface on the plugin. This will check + // if the plugin supports the given interface (with caching) and returns the + // pointer to the proxied interface if it is supported. Returns NULL if the + // given interface isn't supported by the plugin or the proxy. + const void* GetProxiedInterface(const std::string& interface); + private: + friend class HostDispatcherTest; + + enum PluginInterfaceSupport { + INTERFACE_UNQUERIED = 0, // Must be 0 so memset(0) will clear the list. + INTERFACE_SUPPORTED, + INTERFACE_UNSUPPORTED + }; + PluginInterfaceSupport plugin_interface_support_[INTERFACE_ID_COUNT]; + + // All target proxies currently created. These are ones that receive + // messages. They are created on demand when we receive messages. + scoped_ptr<InterfaceProxy> target_proxies_[INTERFACE_ID_COUNT]; + DISALLOW_COPY_AND_ASSIGN(HostDispatcher); }; diff --git a/ppapi/proxy/host_dispatcher_unittest.cc b/ppapi/proxy/host_dispatcher_unittest.cc new file mode 100644 index 0000000..bfa1732 --- /dev/null +++ b/ppapi/proxy/host_dispatcher_unittest.cc @@ -0,0 +1,40 @@ +// 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 "base/scoped_ptr.h" +#include "ipc/ipc_message_utils.h" +#include "ppapi/c/ppb_audio.h" +#include "ppapi/c/ppp_instance.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/ppapi_proxy_test.h" + +namespace pp { +namespace proxy { + +class HostDispatcherTest : public HostProxyTest { + public: + HostDispatcherTest() {} + + bool HasTargetProxy(InterfaceID id) { + return !!host_dispatcher()->target_proxies_[id].get(); + } +}; + +TEST_F(HostDispatcherTest, PPBCreation) { + RegisterTestInterface(PPB_AUDIO_INTERFACE, + reinterpret_cast<void*>(0xdeadbeef)); + + // Sending a PPB message out of the blue should create a target proxy for + // that interface in the plugin. + EXPECT_FALSE(HasTargetProxy(INTERFACE_ID_PPB_AUDIO)); + PpapiMsg_PPBAudio_NotifyAudioStreamCreated audio_msg( + INTERFACE_ID_PPB_AUDIO, HostResource(), 0, + IPC::PlatformFileForTransit(), base::SharedMemoryHandle(), 0); + host_dispatcher()->OnMessageReceived(audio_msg); + EXPECT_TRUE(HasTargetProxy(INTERFACE_ID_PPB_AUDIO)); +} + +} // namespace proxy +} // namespace pp + diff --git a/ppapi/proxy/interface_id.h b/ppapi/proxy/interface_id.h index f2ea1bf..0cce6e9 100644 --- a/ppapi/proxy/interface_id.h +++ b/ppapi/proxy/interface_id.h @@ -23,9 +23,11 @@ enum InterfaceID { INTERFACE_ID_PPB_FLASH, INTERFACE_ID_PPB_FONT, INTERFACE_ID_PPB_FULLSCREEN, + INTERFACE_ID_PPB_GLES_CHROMIUM_TM, INTERFACE_ID_PPB_GRAPHICS_2D, INTERFACE_ID_PPB_IMAGE_DATA, INTERFACE_ID_PPB_INSTANCE, + INTERFACE_ID_PPB_OPENGLES2, INTERFACE_ID_PPB_PDF, INTERFACE_ID_PPB_SURFACE_3D, INTERFACE_ID_PPB_TESTING, diff --git a/ppapi/proxy/interface_proxy.h b/ppapi/proxy/interface_proxy.h index 9c7bba9..400f13a 100644 --- a/ppapi/proxy/interface_proxy.h +++ b/ppapi/proxy/interface_proxy.h @@ -21,28 +21,29 @@ class Dispatcher; class InterfaceProxy : public IPC::Channel::Listener, public IPC::Message::Sender { public: - // Creates the given interface associated with the given dispatcher. The - // dispatcher manages our lifetime. - // - // The target interface pointer, when non-NULL, indicates that this is a - // target proxy (see dispatcher.h for a definition). In this case, the proxy - // will interpret this pointer to the actual implementation of the interface - // in the local process. - // - // If the target interface is NULL, this proxy will be a "source" interface. - InterfaceProxy(Dispatcher* dispatcher, const void* target_interface); - virtual ~InterfaceProxy(); + // Factory function type for interfaces. Ownership of the returned pointer + // is transferred to the caller. + typedef InterfaceProxy* (*Factory)(Dispatcher* dispatcher, + const void* target_interface); - // See dispatcher.h for definitions of source and target. - bool is_source_proxy() const { return !target_interface_; } - bool is_target_proxy() const { return !!target_interface_; } + // Information about the interface. Each interface has a static function to + // return its info, which allows either construction on the target side, and + // getting the proxied interface on the source side (see dispatcher.h for + // terminology). + struct Info { + const void* interface; - // When this proxy is the "target" of the IPC communication (see - // dispatcher.h), this target_interface pointer will indicate the local - // side's interface pointer. This contains the functions that actually - // implement the proxied interface. - // - // This will be NULL when this proxy is a source proxy. + const char* name; + InterfaceID id; + + bool is_trusted; + + InterfaceProxy::Factory create_proxy; + }; + + virtual ~InterfaceProxy(); + + // The actual implementation of the given interface in the current process. const void* target_interface() const { return target_interface_; } Dispatcher* dispatcher() const { return dispatcher_; } @@ -50,18 +51,19 @@ class InterfaceProxy : public IPC::Channel::Listener, // IPC::Message::Sender implementation. virtual bool Send(IPC::Message* msg); - // Returns the local implementation of the interface that will proxy it to - // the remote side. This is used on the source side only (see dispatcher.h). - virtual const void* GetSourceInterface() const = 0; - - // Returns the interface ID associated with this proxy. Implemented by each - // derived class to identify itself. - virtual InterfaceID GetInterfaceId() const = 0; - // Sub-classes must implement IPC::Channel::Listener which contains this: //virtual bool OnMessageReceived(const IPC::Message& msg); protected: + // Creates the given interface associated with the given dispatcher. The + // dispatcher manages our lifetime. + // + // The target interface pointer, when non-NULL, indicates that this is a + // target proxy (see dispatcher.h for a definition). In this case, the proxy + // will interpret this pointer to the actual implementation of the interface + // in the local process. + InterfaceProxy(Dispatcher* dispatcher, const void* target_interface); + uint32 SendCallback(PP_CompletionCallback callback); PP_CompletionCallback ReceiveCallback(uint32 serialized_callback); diff --git a/ppapi/proxy/plugin_dispatcher.cc b/ppapi/proxy/plugin_dispatcher.cc index 48c7ad2..b30f6da 100644 --- a/ppapi/proxy/plugin_dispatcher.cc +++ b/ppapi/proxy/plugin_dispatcher.cc @@ -21,11 +21,15 @@ namespace proxy { namespace { -PluginDispatcher* g_dispatcher = NULL; +typedef std::map<PP_Instance, PluginDispatcher*> InstanceToDispatcherMap; +InstanceToDispatcherMap* g_instance_to_dispatcher = NULL; const void* GetInterfaceFromDispatcher(const char* interface) { - // TODO(brettw) need some kind of lock for multi-thread access. - return pp::proxy::PluginDispatcher::Get()->GetProxiedInterface(interface); + // All interfaces the plugin requests of the browser are "PPB". + const InterfaceProxy::Info* info = Dispatcher::GetPPBInterfaceInfo(interface); + if (!info) + return NULL; + return info->interface; } } // namespace @@ -41,8 +45,7 @@ PluginDispatcher::PluginDispatcher(base::ProcessHandle remote_process_handle, // As a plugin, we always support the PPP_Class interface. There's no // GetInterface call or name for it, so we insert it into our table now. - InjectProxy(INTERFACE_ID_PPP_CLASS, "$Internal_PPP_Class", - new PPP_Class_Proxy(this)); + target_proxies_[INTERFACE_ID_PPP_CLASS].reset(new PPP_Class_Proxy(this)); } PluginDispatcher::~PluginDispatcher() { @@ -51,21 +54,14 @@ PluginDispatcher::~PluginDispatcher() { } // static -PluginDispatcher* PluginDispatcher::Get() { - return g_dispatcher; -} - -// static -void PluginDispatcher::SetGlobal(PluginDispatcher* dispatcher) { - DCHECK(!dispatcher || !g_dispatcher); - g_dispatcher = dispatcher; -} - -// static PluginDispatcher* PluginDispatcher::GetForInstance(PP_Instance instance) { - // TODO(brettw) implement "real" per-instance dispatcher map. - DCHECK(instance != 0); - return Get(); + if (!g_instance_to_dispatcher) + return NULL; + InstanceToDispatcherMap::iterator found = g_instance_to_dispatcher->find( + instance); + if (found == g_instance_to_dispatcher->end()) + return NULL; + return found->second; } bool PluginDispatcher::IsPlugin() const { @@ -73,24 +69,64 @@ bool PluginDispatcher::IsPlugin() const { } bool PluginDispatcher::OnMessageReceived(const IPC::Message& msg) { + // Handle common control messages. + if (Dispatcher::OnMessageReceived(msg)) + return true; + if (msg.routing_id() == MSG_ROUTING_CONTROL) { // Handle some plugin-specific control messages. bool handled = true; IPC_BEGIN_MESSAGE_MAP(PluginDispatcher, msg) + IPC_MESSAGE_HANDLER(PpapiMsg_SupportsInterface, OnMsgSupportsInterface) IPC_MESSAGE_HANDLER(PpapiMsg_InitializeModule, OnMsgInitializeModule) IPC_MESSAGE_HANDLER(PpapiMsg_Shutdown, OnMsgShutdown) - - // Forward all other control messages to the superclass. - IPC_MESSAGE_UNHANDLED(handled = Dispatcher::OnMessageReceived(msg)) IPC_END_MESSAGE_MAP() return handled; } - // All non-control messages get handled by the superclass. - return Dispatcher::OnMessageReceived(msg); + if (msg.routing_id() <= 0 && msg.routing_id() >= INTERFACE_ID_COUNT) { + // Host is sending us garbage. Since it's supposed to be trusted, this + // isn't supposed to happen. Crash here in all builds in case the renderer + // is compromised. + CHECK(false); + return true; + } + + // There are two cases: + // + // * The first case is that the host is calling a PPP interface. It will + // always do a check for the interface before sending messages, and this + // will create the necessary interface proxy at that time. So when we + // actually receive a message, we know such a proxy will exist. + // + // * The second case is that the host is sending a response to the plugin + // side of a PPB interface (some, like the URL loader, have complex + // response messages). Since the host is trusted and not supposed to be + // doing silly things, we can just create a PPB proxy project on demand the + // first time it's needed. + + InterfaceProxy* proxy = target_proxies_[msg.routing_id()].get(); + if (!proxy) { + // Handle the first time the host calls a PPB reply interface by + // autocreating it. + const InterfaceProxy::Info* info = GetPPBInterfaceInfo( + static_cast<InterfaceID>(msg.routing_id())); + if (!info) { + NOTREACHED(); + return true; + } + proxy = info->create_proxy(this, NULL); + target_proxies_[info->id].reset(proxy); + } + + return proxy->OnMessageReceived(msg); } void PluginDispatcher::DidCreateInstance(PP_Instance instance) { + if (!g_instance_to_dispatcher) + g_instance_to_dispatcher = new InstanceToDispatcherMap; + (*g_instance_to_dispatcher)[instance] = this; + instance_map_[instance] = InstanceData(); } @@ -98,6 +134,17 @@ void PluginDispatcher::DidDestroyInstance(PP_Instance instance) { InstanceDataMap::iterator it = instance_map_.find(instance); if (it != instance_map_.end()) instance_map_.erase(it); + + if (g_instance_to_dispatcher) { + InstanceToDispatcherMap::iterator found = g_instance_to_dispatcher->find( + instance); + if (found != g_instance_to_dispatcher->end()) { + DCHECK(found->second == this); + g_instance_to_dispatcher->erase(found); + } else { + NOTREACHED(); + } + } } InstanceData* PluginDispatcher::GetInstanceData(PP_Instance instance) { @@ -117,6 +164,31 @@ void PluginDispatcher::OnMsgShutdown() { MessageLoop::current()->Quit(); } +void PluginDispatcher::OnMsgSupportsInterface( + const std::string& interface_name, + bool* result) { + *result = false; + + // Setup a proxy for receiving the messages from this interface. + const InterfaceProxy::Info* info = GetPPPInterfaceInfo(interface_name); + if (!info) + return; // Interface not supported by proxy. + + // Check for a cached result. + if (target_proxies_[info->id].get()) { + *result = true; + return; + } + + // Query the plugin & cache the result. + const void* interface_functions = GetLocalInterface(interface_name.c_str()); + if (!interface_functions) + return; + target_proxies_[info->id].reset( + info->create_proxy(this, interface_functions)); + *result = true; +} + } // namespace proxy } // namespace pp diff --git a/ppapi/proxy/plugin_dispatcher.h b/ppapi/proxy/plugin_dispatcher.h index d2ab30a..8f27ac0 100644 --- a/ppapi/proxy/plugin_dispatcher.h +++ b/ppapi/proxy/plugin_dispatcher.h @@ -41,23 +41,11 @@ class PluginDispatcher : public Dispatcher { ShutdownModuleFunc shutdown_module); ~PluginDispatcher(); - // Sets/gets the global dispatcher pointer. New code should use the - // GetForInstance version below, this is currently here as a stopgap while - // the transition is being made. - // - // TODO(brettw) remove this. - static PluginDispatcher* Get(); - static void SetGlobal(PluginDispatcher* dispatcher); - // The plugin side maintains a mapping from PP_Instance to Dispatcher so // that we can send the messages to the right channel if there are multiple - // renderers sharing the same plugin. + // renderers sharing the same plugin. This mapping is maintained by + // DidCreateInstance/DidDestroyInstance. static PluginDispatcher* GetForInstance(PP_Instance instance); - /* TODO(brettw) enable this when Get() is removed. - static void SetForInstance(PP_Instance instance, - PluginDispatcher* dispatcher); - static void RemoveForInstance(PP_Instance instance); - */ // Dispatcher overrides. virtual bool IsPlugin() const; @@ -65,8 +53,8 @@ class PluginDispatcher : public Dispatcher { // IPC::Channel::Listener implementation. virtual bool OnMessageReceived(const IPC::Message& msg); - // Keep track of all active instances to associate data with it, like the - // current size. + // Keeps track of which dispatcher to use for each instance, active instances + // and tracks associated data like the current size. void DidCreateInstance(PP_Instance instance); void DidDestroyInstance(PP_Instance instance); @@ -75,13 +63,20 @@ class PluginDispatcher : public Dispatcher { InstanceData* GetInstanceData(PP_Instance instance); private: + friend class PluginDispatcherTest; + // IPC message handlers. void OnMsgInitializeModule(PP_Module pp_module, bool* result); void OnMsgShutdown(); + void OnMsgSupportsInterface(const std::string& interface_name, bool* result); InitModuleFunc init_module_; ShutdownModuleFunc shutdown_module_; + // All target proxies currently created. These are ones that receive + // messages. + scoped_ptr<InterfaceProxy> target_proxies_[INTERFACE_ID_COUNT]; + typedef base::hash_map<PP_Instance, InstanceData> InstanceDataMap; InstanceDataMap instance_map_; diff --git a/ppapi/proxy/plugin_dispatcher_unittest.cc b/ppapi/proxy/plugin_dispatcher_unittest.cc new file mode 100644 index 0000000..f9b624e --- /dev/null +++ b/ppapi/proxy/plugin_dispatcher_unittest.cc @@ -0,0 +1,88 @@ +// 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 "base/scoped_ptr.h" +#include "ipc/ipc_message_utils.h" +#include "ppapi/c/ppb_audio.h" +#include "ppapi/c/ppp_instance.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/ppapi_proxy_test.h" + +namespace pp { +namespace proxy { + +namespace { + +bool received_create = false; + +// Implement PPB_Audio since it's a relatively simple PPB interface and +// includes bidirectional communication. +PP_Resource Create(PP_Instance instance, PP_Resource config, + PPB_Audio_Callback audio_callback, void* user_data) { + received_create = true; + return 0; +} +PP_Bool IsAudio(PP_Resource resource) { + return PP_FALSE; +} +PP_Resource GetCurrentConfig(PP_Resource audio) { + return 0; +} +PP_Bool StartPlayback(PP_Resource audio) { + return PP_FALSE; +} +PP_Bool StopPlayback(PP_Resource audio) { + return PP_FALSE; +} + +PPB_Audio dummy_audio_interface = { + &Create, + &IsAudio, + &GetCurrentConfig, + &StartPlayback, + &StopPlayback +}; + +} // namespace + +class PluginDispatcherTest : public PluginProxyTest { + public: + PluginDispatcherTest() {} + + bool HasTargetProxy(InterfaceID id) { + return !!plugin_dispatcher()->target_proxies_[id].get(); + } +}; + +TEST_F(PluginDispatcherTest, SupportsInterface) { + RegisterTestInterface(PPB_AUDIO_INTERFACE, &dummy_audio_interface); + RegisterTestInterface(PPP_INSTANCE_INTERFACE, + reinterpret_cast<void*>(0xdeadbeef)); + + // Sending a request for a random interface should fail. + EXPECT_FALSE(SupportsInterface("Random interface")); + + // Sending a request for a PPB interface should fail even though we've + // registered it as existing in the GetInterface function (the plugin proxy + // should only respond to PPP interfaces when asked if it supports them). + EXPECT_FALSE(SupportsInterface(PPB_AUDIO_INTERFACE)); + + // Sending a request for a supported PPP interface should succeed. + EXPECT_TRUE(SupportsInterface(PPP_INSTANCE_INTERFACE)); +} + +TEST_F(PluginDispatcherTest, PPBCreation) { + // Sending a PPB message out of the blue should create a target proxy for + // that interface in the plugin. + EXPECT_FALSE(HasTargetProxy(INTERFACE_ID_PPB_AUDIO)); + PpapiMsg_PPBAudio_NotifyAudioStreamCreated audio_msg( + INTERFACE_ID_PPB_AUDIO, HostResource(), 0, + IPC::PlatformFileForTransit(), base::SharedMemoryHandle(), 0); + plugin_dispatcher()->OnMessageReceived(audio_msg); + EXPECT_TRUE(HasTargetProxy(INTERFACE_ID_PPB_AUDIO)); +} + +} // namespace proxy +} // namespace pp + diff --git a/ppapi/proxy/plugin_resource_tracker_unittest.cc b/ppapi/proxy/plugin_resource_tracker_unittest.cc index 4145a13..0df203c 100644 --- a/ppapi/proxy/plugin_resource_tracker_unittest.cc +++ b/ppapi/proxy/plugin_resource_tracker_unittest.cc @@ -45,11 +45,10 @@ class PluginResourceTrackerTest : public PluginProxyTest { }; TEST_F(PluginResourceTrackerTest, PluginResourceForHostResource) { - PP_Instance instance = 0x1234; PP_Resource host_resource = 0x5678; HostResource serialized; - serialized.SetHostResource(instance, host_resource); + serialized.SetHostResource(pp_instance(), host_resource); // When we haven't added an object, the return value should be 0. EXPECT_EQ(0, tracker().PluginResourceForHostResource(serialized)); diff --git a/ppapi/proxy/plugin_var_serialization_rules.cc b/ppapi/proxy/plugin_var_serialization_rules.cc index a56e5b4..a3d8231 100644 --- a/ppapi/proxy/plugin_var_serialization_rules.cc +++ b/ppapi/proxy/plugin_var_serialization_rules.cc @@ -4,6 +4,7 @@ #include "ppapi/proxy/plugin_var_serialization_rules.h" +#include "base/logging.h" #include "ppapi/proxy/plugin_dispatcher.h" #include "ppapi/proxy/plugin_var_tracker.h" @@ -42,8 +43,11 @@ PP_Var PluginVarSerializationRules::BeginReceiveCallerOwned( return ret; } - if (var.type == PP_VARTYPE_OBJECT) - return var_tracker_->TrackObjectWithNoReference(var, dispatcher); + if (var.type == PP_VARTYPE_OBJECT) { + DCHECK(dispatcher->IsPlugin()); + return var_tracker_->TrackObjectWithNoReference( + var, static_cast<PluginDispatcher*>(dispatcher)); + } return var; } @@ -85,7 +89,9 @@ PP_Var PluginVarSerializationRules::ReceivePassRef(const PP_Var& var, // folded in to its set of refs it maintains (with one ref representing all // fo them in the browser). if (var.type == PP_VARTYPE_OBJECT) { - return var_tracker_->ReceiveObjectPassRef(var, dispatcher); + DCHECK(dispatcher->IsPlugin()); + return var_tracker_->ReceiveObjectPassRef( + var, static_cast<PluginDispatcher*>(dispatcher)); } // Other types are unchanged. @@ -124,8 +130,10 @@ void PluginVarSerializationRules::EndSendPassRef(const PP_Var& var, // The var we have in our inner class has been converted to a host object // by BeginSendPassRef. This means it's not a normal var valid in the plugin, // so we need to use the special ReleaseHostObject. - if (var.type == PP_VARTYPE_OBJECT) - var_tracker_->ReleaseHostObject(dispatcher, var); + if (var.type == PP_VARTYPE_OBJECT) { + var_tracker_->ReleaseHostObject( + static_cast<PluginDispatcher*>(dispatcher), var); + } } void PluginVarSerializationRules::ReleaseObjectRef(const PP_Var& var) { diff --git a/ppapi/proxy/plugin_var_tracker.cc b/ppapi/proxy/plugin_var_tracker.cc index c079716..8f7fd38 100644 --- a/ppapi/proxy/plugin_var_tracker.cc +++ b/ppapi/proxy/plugin_var_tracker.cc @@ -7,6 +7,7 @@ #include "base/ref_counted.h" #include "base/singleton.h" #include "ppapi/c/ppb_var.h" +#include "ppapi/proxy/plugin_dispatcher.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/interface_id.h" @@ -42,15 +43,15 @@ RefCountedString* PluginStringFromID(PluginVarTracker::VarID id) { } // namespace -PluginVarTracker::HostVar::HostVar(Sender* d, VarID i) - : channel(d), +PluginVarTracker::HostVar::HostVar(PluginDispatcher* d, VarID i) + : dispatcher(d), host_object_id(i) { } bool PluginVarTracker::HostVar::operator<(const HostVar& other) const { - if (channel < other.channel) + if (dispatcher < other.dispatcher) return true; - if (other.channel < channel) + if (other.dispatcher < dispatcher) return false; return host_object_id < other.host_object_id; } @@ -149,12 +150,12 @@ void PluginVarTracker::Release(const PP_Var& var) { } PP_Var PluginVarTracker::ReceiveObjectPassRef(const PP_Var& var, - Sender* channel) { + PluginDispatcher* dispatcher) { DCHECK(var.type == PP_VARTYPE_OBJECT); // Find the plugin info. PluginVarInfoMap::iterator found = - FindOrMakePluginVarFromHostVar(var, channel); + FindOrMakePluginVarFromHostVar(var, dispatcher); if (found == plugin_var_info_.end()) { // The above code should have always made an entry in the map. NOTREACHED(); @@ -184,12 +185,13 @@ PP_Var PluginVarTracker::ReceiveObjectPassRef(const PP_Var& var, return ret; } -PP_Var PluginVarTracker::TrackObjectWithNoReference(const PP_Var& host_var, - Sender* channel) { +PP_Var PluginVarTracker::TrackObjectWithNoReference( + const PP_Var& host_var, + PluginDispatcher* dispatcher) { DCHECK(host_var.type == PP_VARTYPE_OBJECT); PluginVarInfoMap::iterator found = - FindOrMakePluginVarFromHostVar(host_var, channel); + FindOrMakePluginVarFromHostVar(host_var, dispatcher); if (found == plugin_var_info_.end()) { // The above code should have always made an entry in the map. NOTREACHED(); @@ -232,12 +234,22 @@ PP_Var PluginVarTracker::GetHostObject(const PP_Var& plugin_object) const { return ret; } -void PluginVarTracker::ReleaseHostObject(Sender* sender, +PluginDispatcher* PluginVarTracker::DispatcherForPluginObject( + const PP_Var& plugin_object) const { + DCHECK(plugin_object.type == PP_VARTYPE_OBJECT); + PluginVarInfoMap::const_iterator found = plugin_var_info_.find( + plugin_object.value.as_id); + if (found != plugin_var_info_.end()) + return found->second.host_var.dispatcher; + return NULL; +} + +void PluginVarTracker::ReleaseHostObject(PluginDispatcher* dispatcher, const PP_Var& host_object) { // Convert the host object to a normal var valid in the plugin. DCHECK(host_object.type == PP_VARTYPE_OBJECT); HostVarToPluginVarMap::iterator found = host_var_to_plugin_var_.find( - HostVar(sender, host_object.value.as_id)); + HostVar(dispatcher, host_object.value.as_id)); if (found == host_var_to_plugin_var_.end()) { NOTREACHED(); return; @@ -268,20 +280,20 @@ int PluginVarTracker::GetTrackedWithNoReferenceCountForObject( } void PluginVarTracker::SendAddRefObjectMsg(const HostVar& host_var) { - host_var.channel->Send(new PpapiHostMsg_PPBVar_AddRefObject( + host_var.dispatcher->Send(new PpapiHostMsg_PPBVar_AddRefObject( INTERFACE_ID_PPB_VAR_DEPRECATED, host_var.host_object_id)); } void PluginVarTracker::SendReleaseObjectMsg(const HostVar& host_var) { - host_var.channel->Send(new PpapiHostMsg_PPBVar_ReleaseObject( + host_var.dispatcher->Send(new PpapiHostMsg_PPBVar_ReleaseObject( INTERFACE_ID_PPB_VAR_DEPRECATED, host_var.host_object_id)); } PluginVarTracker::PluginVarInfoMap::iterator PluginVarTracker::FindOrMakePluginVarFromHostVar(const PP_Var& var, - Sender* channel) { + PluginDispatcher* dispatcher) { DCHECK(var.type == PP_VARTYPE_OBJECT); - HostVar host_var(channel, var.value.as_id); + HostVar host_var(dispatcher, var.value.as_id); HostVarToPluginVarMap::iterator found = host_var_to_plugin_var_.find(host_var); diff --git a/ppapi/proxy/plugin_var_tracker.h b/ppapi/proxy/plugin_var_tracker.h index 21cd4594..24f6818 100644 --- a/ppapi/proxy/plugin_var_tracker.h +++ b/ppapi/proxy/plugin_var_tracker.h @@ -8,7 +8,6 @@ #include <map> #include <string> -#include "ipc/ipc_channel.h" #include "ppapi/c/pp_stdint.h" #include "ppapi/c/pp_var.h" @@ -19,6 +18,8 @@ template<typename T> struct DefaultSingletonTraits; namespace pp { namespace proxy { +class PluginDispatcher; + // Tracks live strings and objects in the plugin process. // // This object maintains its own object IDs that are used by the plugin. These @@ -38,12 +39,6 @@ class PluginVarTracker { public: typedef int64_t VarID; - // This uses the PluginDispatcher to identify the source of vars so that - // the proper messages can be sent back. However, since all we need is the - // ability to send messages, we can always use the Sender base class of - // Dispatcher in this class, which makes it easy to unit test. - typedef IPC::Channel::Sender Sender; - // Called by tests that want to specify a specific VarTracker. This allows // them to use a unique one each time and avoids singletons sticking around // across tests. @@ -70,19 +65,23 @@ class PluginVarTracker { // Manages tracking for receiving a VARTYPE_OBJECT from the remote side // (either the plugin or the renderer) that has already had its reference // count incremented on behalf of the caller. - PP_Var ReceiveObjectPassRef(const PP_Var& var, Sender* channel); + PP_Var ReceiveObjectPassRef(const PP_Var& var, PluginDispatcher* dispatcher); PP_Var TrackObjectWithNoReference(const PP_Var& host_var, - Sender* channel); + PluginDispatcher* dispatcher); void StopTrackingObjectWithNoReference(const PP_Var& plugin_var); // Returns the host var for the corresponding plugin object var. The object // should be a VARTYPE_OBJECT PP_Var GetHostObject(const PP_Var& plugin_object) const; + PluginDispatcher* DispatcherForPluginObject( + const PP_Var& plugin_object) const; + // Like Release() but the var is identified by its host object ID (as // returned by GetHostObject). - void ReleaseHostObject(Sender* sender, const PP_Var& host_object); + void ReleaseHostObject(PluginDispatcher* dispatcher, + const PP_Var& host_object); // Retrieves the internal reference counts for testing. Returns 0 if we // know about the object but the corresponding value is 0, or -1 if the @@ -96,13 +95,13 @@ class PluginVarTracker { // Represents a var as received from the host. struct HostVar { - HostVar(Sender* s, int64_t i); + HostVar(PluginDispatcher* d, int64_t i); bool operator<(const HostVar& other) const; - // The host that sent us this object. This is used so we know how to send - // back requests on this object. - Sender* channel; + // The dispatcher that sent us this object. This is used so we know how to + // send back requests on this object. + PluginDispatcher* dispatcher; // The object ID that the host generated to identify the object. This is // unique only within that host: different hosts could give us different @@ -145,7 +144,7 @@ class PluginVarTracker { PluginVarInfoMap::iterator FindOrMakePluginVarFromHostVar( const PP_Var& var, - Sender* channel); + PluginDispatcher* dispatcher); // Checks the reference counds of the given plugin var info and removes the // tracking information if necessary. We're done with the object when its diff --git a/ppapi/proxy/plugin_var_tracker_unittest.cc b/ppapi/proxy/plugin_var_tracker_unittest.cc index 25663f9..3f7e220 100644 --- a/ppapi/proxy/plugin_var_tracker_unittest.cc +++ b/ppapi/proxy/plugin_var_tracker_unittest.cc @@ -69,8 +69,8 @@ TEST_F(PluginVarTrackerTest, GetHostObject) { // Round-trip through the tracker to make sure the host object comes out the // other end. - PP_Var plugin_object = var_tracker().ReceiveObjectPassRef(host_object, - &sink()); + PP_Var plugin_object = var_tracker().ReceiveObjectPassRef( + host_object, plugin_dispatcher()); PP_Var host_object2 = var_tracker().GetHostObject(plugin_object); EXPECT_EQ(PP_VARTYPE_OBJECT, host_object2.type); EXPECT_EQ(host_object.value.as_id, host_object2.value.as_id); @@ -82,16 +82,16 @@ TEST_F(PluginVarTrackerTest, ReceiveObjectPassRef) { PP_Var host_object = MakeObject(12345); // Receive the object, we should have one ref and no messages. - PP_Var plugin_object = var_tracker().ReceiveObjectPassRef(host_object, - &sink()); + PP_Var plugin_object = var_tracker().ReceiveObjectPassRef( + host_object, plugin_dispatcher()); EXPECT_EQ(0u, sink().message_count()); EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_object)); EXPECT_EQ(0, var_tracker().GetTrackedWithNoReferenceCountForObject(plugin_object)); // Receive the same object again, we should get the same plugin ID out. - PP_Var plugin_object2 = var_tracker().ReceiveObjectPassRef(host_object, - &sink()); + PP_Var plugin_object2 = var_tracker().ReceiveObjectPassRef( + host_object, plugin_dispatcher()); EXPECT_EQ(plugin_object.value.as_id, plugin_object2.value.as_id); EXPECT_EQ(2, var_tracker().GetRefCountForObject(plugin_object)); EXPECT_EQ(0, @@ -117,9 +117,10 @@ TEST_F(PluginVarTrackerTest, FreeTrackedAndReferencedObject) { PP_Var host_object = MakeObject(12345); // Phase one: First receive via a "pass ref", then a tracked with no ref. - PP_Var plugin_var = var_tracker().ReceiveObjectPassRef(host_object, &sink()); - PP_Var plugin_var2 = - var_tracker().TrackObjectWithNoReference(host_object, &sink()); + PP_Var plugin_var = var_tracker().ReceiveObjectPassRef( + host_object, plugin_dispatcher()); + PP_Var plugin_var2 = var_tracker().TrackObjectWithNoReference( + host_object, plugin_dispatcher()); EXPECT_EQ(plugin_var.value.as_id, plugin_var2.value.as_id); EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_var)); EXPECT_EQ(1, @@ -138,8 +139,10 @@ TEST_F(PluginVarTrackerTest, FreeTrackedAndReferencedObject) { // Phase two: Receive via a tracked, then get an addref. sink().ClearMessages(); - plugin_var = var_tracker().TrackObjectWithNoReference(host_object, &sink()); - plugin_var2 = var_tracker().ReceiveObjectPassRef(host_object, &sink()); + plugin_var = var_tracker().TrackObjectWithNoReference( + host_object, plugin_dispatcher()); + plugin_var2 = var_tracker().ReceiveObjectPassRef( + host_object, plugin_dispatcher()); EXPECT_EQ(plugin_var.value.as_id, plugin_var2.value.as_id); EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_var)); EXPECT_EQ(1, @@ -162,11 +165,11 @@ TEST_F(PluginVarTrackerTest, RecursiveTrackWithNoRef) { // Receive a tracked object twice. PP_Var plugin_var = var_tracker().TrackObjectWithNoReference( - host_object, &sink()); + host_object, plugin_dispatcher()); EXPECT_EQ(1, var_tracker().GetTrackedWithNoReferenceCountForObject(plugin_var)); - PP_Var plugin_var2 = var_tracker().TrackObjectWithNoReference(host_object, - &sink()); + PP_Var plugin_var2 = var_tracker().TrackObjectWithNoReference( + host_object, plugin_dispatcher()); EXPECT_EQ(plugin_var.value.as_id, plugin_var2.value.as_id); EXPECT_EQ(0, var_tracker().GetRefCountForObject(plugin_var)); EXPECT_EQ(2, diff --git a/ppapi/proxy/ppapi_messages_internal.h b/ppapi/proxy/ppapi_messages_internal.h index 2bc4da4..b181b2e 100644 --- a/ppapi/proxy/ppapi_messages_internal.h +++ b/ppapi/proxy/ppapi_messages_internal.h @@ -29,11 +29,6 @@ IPC_SYNC_MESSAGE_CONTROL1_1(PpapiMsg_SupportsInterface, std::string /* interface_name */, bool /* result */) -// Way for the renderer to list all interfaces that is supports in advance to -// avoid extra IPC traffic. -IPC_MESSAGE_CONTROL1(PpapiMsg_DeclareInterfaces, - std::vector<std::string> /* interfaces */) - IPC_MESSAGE_CONTROL2(PpapiMsg_ExecuteCallback, uint32 /* serialized_callback */, int32 /* param */) diff --git a/ppapi/proxy/ppapi_proxy_test.cc b/ppapi/proxy/ppapi_proxy_test.cc index 240860c..1b75001 100644 --- a/ppapi/proxy/ppapi_proxy_test.cc +++ b/ppapi/proxy/ppapi_proxy_test.cc @@ -5,14 +5,21 @@ #include "ppapi/proxy/ppapi_proxy_test.h" #include "ppapi/c/pp_errors.h" +#include "ppapi/proxy/ppapi_messages.h" namespace pp { namespace proxy { namespace { -const void* MockGetInterface(const char*) { - return NULL; +ProxyTestBase* current_test = NULL; + +const void* MockGetInterface(const char* name) { + if (!current_test) { + NOTREACHED(); + return NULL; + } + return current_test->GetInterface(name); } int32_t MockInitModule(PP_Module, Dispatcher::GetInterfaceFunc) { @@ -24,36 +31,109 @@ void MockShutdownModuleFunc() { } // namespace +// ProxyTestBase --------------------------------------------------------------- + +ProxyTestBase::ProxyTestBase() : pp_module_(0x98765), pp_instance_(0x12345) { + DCHECK(!current_test); + current_test = this; +} + +ProxyTestBase::~ProxyTestBase() { + DCHECK(current_test == this); + current_test = NULL; +} + +const void* ProxyTestBase::GetInterface(const char* name) { + return registered_interfaces_[name]; +} + +void ProxyTestBase::RegisterTestInterface(const char* name, + const void* interface) { + registered_interfaces_[name] = interface; +} + +bool ProxyTestBase::SupportsInterface(const char* name) { + sink().ClearMessages(); + + // IPC doesn't actually write to this when we send a message manually + // not actually using IPC. + bool unused_result = false; + PpapiMsg_SupportsInterface msg(name, &unused_result); + GetDispatcher()->OnMessageReceived(msg); + + const IPC::Message* reply_msg = + sink().GetUniqueMessageMatching(IPC_REPLY_ID); + EXPECT_TRUE(reply_msg); + if (!reply_msg) + return false; + + TupleTypes<PpapiMsg_SupportsInterface::ReplyParam>::ValueTuple reply_data; + EXPECT_TRUE(PpapiMsg_SupportsInterface::ReadReplyParam( + reply_msg, &reply_data)); + + sink().ClearMessages(); + return reply_data.a; +} + +// PluginProxyTest ------------------------------------------------------------- + PluginProxyTest::PluginProxyTest() { } PluginProxyTest::~PluginProxyTest() { } +Dispatcher* PluginProxyTest::GetDispatcher() { + return plugin_dispatcher_.get(); +} + void PluginProxyTest::SetUp() { // These must be first since the dispatcher set-up uses them. PluginResourceTracker::SetInstanceForTest(&resource_tracker_); PluginVarTracker::SetInstanceForTest(&var_tracker_); - pp_instance_ = 0x1234; plugin_dispatcher_.reset(new PluginDispatcher( base::Process::Current().handle(), &MockGetInterface, &MockInitModule, &MockShutdownModuleFunc)); - plugin_dispatcher_->InitWithTestSink(&sink_); - // When the plugin dispatcher is per-instance, this is the line to use: - // PluginDispatcher::SetForInstance(pp_instance_, plugin_dispatcher_.get()); - PluginDispatcher::SetGlobal(plugin_dispatcher_.get()); + plugin_dispatcher_->InitWithTestSink(&sink()); + plugin_dispatcher_->DidCreateInstance(pp_instance()); } void PluginProxyTest::TearDown() { - PluginDispatcher::SetGlobal(NULL); + plugin_dispatcher_->DidDestroyInstance(pp_instance()); plugin_dispatcher_.reset(); PluginVarTracker::SetInstanceForTest(NULL); PluginResourceTracker::SetInstanceForTest(NULL); } +// HostProxyTest --------------------------------------------------------------- + +HostProxyTest::HostProxyTest() { +} + +HostProxyTest::~HostProxyTest() { +} + +Dispatcher* HostProxyTest::GetDispatcher() { + return host_dispatcher_.get(); +} + +void HostProxyTest::SetUp() { + host_dispatcher_.reset(new HostDispatcher( + base::Process::Current().handle(), + pp_module(), + &MockGetInterface)); + host_dispatcher_->InitWithTestSink(&sink()); + HostDispatcher::SetForInstance(pp_instance(), host_dispatcher_.get()); +} + +void HostProxyTest::TearDown() { + HostDispatcher::RemoveForInstance(pp_instance()); + host_dispatcher_.reset(); +} + } // namespace proxy } // namespace pp diff --git a/ppapi/proxy/ppapi_proxy_test.h b/ppapi/proxy/ppapi_proxy_test.h index a811080..d3c867a 100644 --- a/ppapi/proxy/ppapi_proxy_test.h +++ b/ppapi/proxy/ppapi_proxy_test.h @@ -2,9 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <map> +#include <string> + #include "base/scoped_ptr.h" #include "ipc/ipc_test_sink.h" #include "ppapi/c/pp_instance.h" +#include "ppapi/proxy/host_dispatcher.h" #include "ppapi/proxy/plugin_dispatcher.h" #include "ppapi/proxy/plugin_resource_tracker.h" #include "ppapi/proxy/plugin_var_tracker.h" @@ -13,33 +17,85 @@ namespace pp { namespace proxy { -// Test harness for the plugin side of the proxy. -class PluginProxyTest : public testing::Test { +// Base class for plugin and host tests. Tests will not use this directly. +// Instead, use the Plugin or HostProxyTest. +class ProxyTestBase : public testing::Test { public: - PluginProxyTest(); - ~PluginProxyTest(); - - virtual void SetUp(); - virtual void TearDown(); + ProxyTestBase(); + virtual ~ProxyTestBase(); - // The instance ID associated with the plugin dispatcher. + PP_Module pp_module() const { return pp_module_; } PP_Instance pp_instance() const { return pp_instance_; } + IPC::TestSink& sink() { return sink_; } - PluginDispatcher* plugin_dispatcher() { return plugin_dispatcher_.get(); } + // Returns either the plugin or host dispatcher, depending on the test. + virtual Dispatcher* GetDispatcher() = 0; + + // Implementation of GetInterface for the dispatcher. This will + // return NULL for all interfaces unless one is registered by calling + // RegisterTestInterface(); + const void* GetInterface(const char* name); + + // Allows the test to specify an interface implementation for a given + // interface name. This will be returned when any of the proxy logic + // requests a local interface. + void RegisterTestInterface(const char* name, const void* interface); + // Sends a "supports interface" message to the current dispatcher and returns + // true if it's supported. This is just for the convenience of tests. + bool SupportsInterface(const char* name); + + private: + // Destination for IPC messages sent by the test. + IPC::TestSink sink_; + + // The module and instance ID associated with the plugin dispatcher. + PP_Module pp_module_; + PP_Instance pp_instance_; + + // Stores the data for GetInterface/RegisterTestInterface. + std::map<std::string, const void*> registered_interfaces_; +}; + +// Test harness for the plugin side of the proxy. +class PluginProxyTest : public ProxyTestBase { + public: + PluginProxyTest(); + virtual ~PluginProxyTest(); + + PluginDispatcher* plugin_dispatcher() { return plugin_dispatcher_.get(); } PluginResourceTracker& resource_tracker() { return resource_tracker_; } PluginVarTracker& var_tracker() { return var_tracker_; } - IPC::TestSink& sink() { return sink_; } + // ProxyTestBase implementation. + virtual Dispatcher* GetDispatcher(); + + // testing::Test implementation. + virtual void SetUp(); + virtual void TearDown(); private: PluginResourceTracker resource_tracker_; PluginVarTracker var_tracker_; - - PP_Instance pp_instance_; scoped_ptr<PluginDispatcher> plugin_dispatcher_; +}; - IPC::TestSink sink_; +class HostProxyTest : public ProxyTestBase { + public: + HostProxyTest(); + virtual ~HostProxyTest(); + + HostDispatcher* host_dispatcher() { return host_dispatcher_.get(); } + + // ProxyTestBase implementation. + virtual Dispatcher* GetDispatcher(); + + // testing::Test implementation. + virtual void SetUp(); + virtual void TearDown(); + + private: + scoped_ptr<HostDispatcher> host_dispatcher_; }; } // namespace proxy diff --git a/ppapi/proxy/ppb_audio_config_proxy.cc b/ppapi/proxy/ppb_audio_config_proxy.cc index 15b0987..0c8eaab 100644 --- a/ppapi/proxy/ppb_audio_config_proxy.cc +++ b/ppapi/proxy/ppb_audio_config_proxy.cc @@ -95,6 +95,11 @@ const PPB_AudioConfig audio_config_interface = { &GetSampleFrameCount }; +InterfaceProxy* CreateAudioConfigProxy(Dispatcher* dispatcher, + const void* target_interface) { + return new PPB_AudioConfig_Proxy(dispatcher, target_interface); +} + } // namespace PPB_AudioConfig_Proxy::PPB_AudioConfig_Proxy(Dispatcher* dispatcher, @@ -105,12 +110,16 @@ PPB_AudioConfig_Proxy::PPB_AudioConfig_Proxy(Dispatcher* dispatcher, PPB_AudioConfig_Proxy::~PPB_AudioConfig_Proxy() { } -const void* PPB_AudioConfig_Proxy::GetSourceInterface() const { - return &audio_config_interface; -} - -InterfaceID PPB_AudioConfig_Proxy::GetInterfaceId() const { - return INTERFACE_ID_PPB_AUDIO_CONFIG; +// static +const InterfaceProxy::Info* PPB_AudioConfig_Proxy::GetInfo() { + static const Info info = { + &audio_config_interface, + PPB_AUDIO_CONFIG_INTERFACE, + INTERFACE_ID_PPB_AUDIO_CONFIG, + false, + &CreateAudioConfigProxy, + }; + return &info; } bool PPB_AudioConfig_Proxy::OnMessageReceived(const IPC::Message& msg) { diff --git a/ppapi/proxy/ppb_audio_config_proxy.h b/ppapi/proxy/ppb_audio_config_proxy.h index 6492ae1..c6c9588 100644 --- a/ppapi/proxy/ppb_audio_config_proxy.h +++ b/ppapi/proxy/ppb_audio_config_proxy.h @@ -22,13 +22,13 @@ class PPB_AudioConfig_Proxy : public InterfaceProxy { PPB_AudioConfig_Proxy(Dispatcher* dispatcher, const void* target_interface); virtual ~PPB_AudioConfig_Proxy(); + static const Info* GetInfo(); + const PPB_AudioConfig* ppb_audio_config_target() const { return static_cast<const PPB_AudioConfig*>(target_interface()); } // InterfaceProxy implementation. - virtual const void* GetSourceInterface() const; - virtual InterfaceID GetInterfaceId() const; virtual bool OnMessageReceived(const IPC::Message& msg); private: diff --git a/ppapi/proxy/ppb_audio_proxy.cc b/ppapi/proxy/ppb_audio_proxy.cc index a01e785..6adc436 100644 --- a/ppapi/proxy/ppb_audio_proxy.cc +++ b/ppapi/proxy/ppb_audio_proxy.cc @@ -72,8 +72,12 @@ PP_Resource Create(PP_Instance instance_id, if (!config) return 0; + PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance_id); + if (!dispatcher) + return 0; + HostResource result; - PluginDispatcher::Get()->Send(new PpapiHostMsg_PPBAudio_Create( + dispatcher->Send(new PpapiHostMsg_PPBAudio_Create( INTERFACE_ID_PPB_AUDIO, instance_id, config->host_resource(), &result)); if (result.is_null()) return 0; @@ -120,6 +124,11 @@ const PPB_Audio audio_interface = { &StopPlayback }; +InterfaceProxy* CreateAudioProxy(Dispatcher* dispatcher, + const void* target_interface) { + return new PPB_Audio_Proxy(dispatcher, target_interface); +} + } // namespace PPB_Audio_Proxy::PPB_Audio_Proxy(Dispatcher* dispatcher, @@ -131,12 +140,16 @@ PPB_Audio_Proxy::PPB_Audio_Proxy(Dispatcher* dispatcher, PPB_Audio_Proxy::~PPB_Audio_Proxy() { } -const void* PPB_Audio_Proxy::GetSourceInterface() const { - return &audio_interface; -} - -InterfaceID PPB_Audio_Proxy::GetInterfaceId() const { - return INTERFACE_ID_PPB_AUDIO; +// static +const InterfaceProxy::Info* PPB_Audio_Proxy::GetInfo() { + static const Info info = { + &audio_interface, + PPB_AUDIO_INTERFACE, + INTERFACE_ID_PPB_AUDIO, + false, + &CreateAudioProxy, + }; + return &info; } bool PPB_Audio_Proxy::OnMessageReceived(const IPC::Message& msg) { diff --git a/ppapi/proxy/ppb_audio_proxy.h b/ppapi/proxy/ppb_audio_proxy.h index 02ecb5c..6574ef7 100644 --- a/ppapi/proxy/ppb_audio_proxy.h +++ b/ppapi/proxy/ppb_audio_proxy.h @@ -28,13 +28,13 @@ class PPB_Audio_Proxy : public InterfaceProxy { PPB_Audio_Proxy(Dispatcher* dispatcher, const void* target_interface); virtual ~PPB_Audio_Proxy(); + static const Info* GetInfo(); + const PPB_Audio* ppb_audio_target() const { return static_cast<const PPB_Audio*>(target_interface()); } // InterfaceProxy implementation. - virtual const void* GetSourceInterface() const; - virtual InterfaceID GetInterfaceId() const; virtual bool OnMessageReceived(const IPC::Message& msg); private: diff --git a/ppapi/proxy/ppb_buffer_proxy.cc b/ppapi/proxy/ppb_buffer_proxy.cc index 5125855..a74bf18 100644 --- a/ppapi/proxy/ppb_buffer_proxy.cc +++ b/ppapi/proxy/ppb_buffer_proxy.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -109,7 +109,7 @@ void Unmap(PP_Resource resource) { object->Unmap(); } -const PPB_Buffer_Dev ppb_buffer = { +const PPB_Buffer_Dev buffer_interface = { &Create, &IsBuffer, &Describe, @@ -117,6 +117,11 @@ const PPB_Buffer_Dev ppb_buffer = { &Unmap, }; +InterfaceProxy* CreateBufferProxy(Dispatcher* dispatcher, + const void* target_interface) { + return new PPB_Buffer_Proxy(dispatcher, target_interface); +} + } // namespace PPB_Buffer_Proxy::PPB_Buffer_Proxy(Dispatcher* dispatcher, @@ -127,12 +132,16 @@ PPB_Buffer_Proxy::PPB_Buffer_Proxy(Dispatcher* dispatcher, PPB_Buffer_Proxy::~PPB_Buffer_Proxy() { } -const void* PPB_Buffer_Proxy::GetSourceInterface() const { - return &ppb_buffer; -} - -InterfaceID PPB_Buffer_Proxy::GetInterfaceId() const { - return INTERFACE_ID_PPB_BUFFER; +// static +const InterfaceProxy::Info* PPB_Buffer_Proxy::GetInfo() { + static const Info info = { + &buffer_interface, + PPB_BUFFER_DEV_INTERFACE, + INTERFACE_ID_PPB_BUFFER, + false, + &CreateBufferProxy, + }; + return &info; } bool PPB_Buffer_Proxy::OnMessageReceived(const IPC::Message& msg) { diff --git a/ppapi/proxy/ppb_buffer_proxy.h b/ppapi/proxy/ppb_buffer_proxy.h index bc979a3..1294be5 100644 --- a/ppapi/proxy/ppb_buffer_proxy.h +++ b/ppapi/proxy/ppb_buffer_proxy.h @@ -20,13 +20,13 @@ class PPB_Buffer_Proxy : public InterfaceProxy { PPB_Buffer_Proxy(Dispatcher* dispatcher, const void* target_interface); virtual ~PPB_Buffer_Proxy(); + static const Info* GetInfo(); + const PPB_Buffer_Dev* ppb_buffer_target() const { return static_cast<const PPB_Buffer_Dev*>(target_interface()); } // InterfaceProxy implementation. - virtual const void* GetSourceInterface() const; - virtual InterfaceID GetInterfaceId() const; virtual bool OnMessageReceived(const IPC::Message& msg); private: diff --git a/ppapi/proxy/ppb_char_set_proxy.cc b/ppapi/proxy/ppb_char_set_proxy.cc index 73ca61b..35b6473 100644 --- a/ppapi/proxy/ppb_char_set_proxy.cc +++ b/ppapi/proxy/ppb_char_set_proxy.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -79,12 +79,17 @@ PP_Var GetDefaultCharSet(PP_Instance instance) { return result.Return(dispatcher); } -const PPB_CharSet_Dev ppb_charset_interface = { +const PPB_CharSet_Dev charset_interface = { &UTF16ToCharSet, &CharSetToUTF16, &GetDefaultCharSet }; +InterfaceProxy* CreateCharSetProxy(Dispatcher* dispatcher, + const void* target_interface) { + return new PPB_CharSet_Proxy(dispatcher, target_interface); +} + } // namespace PPB_CharSet_Proxy::PPB_CharSet_Proxy(Dispatcher* dispatcher, @@ -96,12 +101,16 @@ PPB_CharSet_Proxy::PPB_CharSet_Proxy(Dispatcher* dispatcher, PPB_CharSet_Proxy::~PPB_CharSet_Proxy() { } -const void* PPB_CharSet_Proxy::GetSourceInterface() const { - return &ppb_charset_interface; -} - -InterfaceID PPB_CharSet_Proxy::GetInterfaceId() const { - return INTERFACE_ID_PPB_CHAR_SET; +// static +const InterfaceProxy::Info* PPB_CharSet_Proxy::GetInfo() { + static const Info info = { + &charset_interface, + PPB_CHAR_SET_DEV_INTERFACE, + INTERFACE_ID_PPB_CHAR_SET, + false, + &CreateCharSetProxy, + }; + return &info; } bool PPB_CharSet_Proxy::OnMessageReceived(const IPC::Message& msg) { diff --git a/ppapi/proxy/ppb_char_set_proxy.h b/ppapi/proxy/ppb_char_set_proxy.h index 7a80fcb..91360b1 100644 --- a/ppapi/proxy/ppb_char_set_proxy.h +++ b/ppapi/proxy/ppb_char_set_proxy.h @@ -23,13 +23,13 @@ class PPB_CharSet_Proxy : public InterfaceProxy { PPB_CharSet_Proxy(Dispatcher* dispatcher, const void* target_interface); virtual ~PPB_CharSet_Proxy(); + static const Info* GetInfo(); + const PPB_CharSet_Dev* ppb_char_set_target() const { return static_cast<const PPB_CharSet_Dev*>(target_interface()); } // InterfaceProxy implementation. - virtual const void* GetSourceInterface() const; - virtual InterfaceID GetInterfaceId() const; virtual bool OnMessageReceived(const IPC::Message& msg); private: diff --git a/ppapi/proxy/ppb_context_3d_proxy.cc b/ppapi/proxy/ppb_context_3d_proxy.cc index 9650c84..9c1e383 100644 --- a/ppapi/proxy/ppb_context_3d_proxy.cc +++ b/ppapi/proxy/ppb_context_3d_proxy.cc @@ -123,7 +123,7 @@ int32_t GetBoundSurfaces(PP_Resource context, } -const PPB_Context3D_Dev ppb_context_3d = { +const PPB_Context3D_Dev context_3d_interface = { &Create, &IsContext3D, &GetAttrib, @@ -156,6 +156,11 @@ gpu::CommandBuffer::State GPUStateFromPPState( const int32 kCommandBufferSize = 1024 * 1024; const int32 kTransferBufferSize = 1024 * 1024; +InterfaceProxy* CreateContext3DProxy(Dispatcher* dispatcher, + const void* target_interface) { + return new PPB_Context3D_Proxy(dispatcher, target_interface); +} + } // namespace class PepperCommandBuffer : public gpu::CommandBuffer { @@ -446,6 +451,18 @@ PPB_Context3D_Proxy::PPB_Context3D_Proxy(Dispatcher* dispatcher, PPB_Context3D_Proxy::~PPB_Context3D_Proxy() { } +// static +const InterfaceProxy::Info* PPB_Context3D_Proxy::GetInfo() { + static const Info info = { + &context_3d_interface, + PPB_CONTEXT_3D_DEV_INTERFACE, + INTERFACE_ID_PPB_CONTEXT_3D, + false, + &CreateContext3DProxy, + }; + return &info; +} + const PPB_Context3DTrusted_Dev* PPB_Context3D_Proxy::ppb_context_3d_trusted() const { return static_cast<const PPB_Context3DTrusted_Dev*>( @@ -453,14 +470,6 @@ PPB_Context3D_Proxy::ppb_context_3d_trusted() const { PPB_CONTEXT_3D_TRUSTED_DEV_INTERFACE)); } -const void* PPB_Context3D_Proxy::GetSourceInterface() const { - return &ppb_context_3d; -} - -InterfaceID PPB_Context3D_Proxy::GetInterfaceId() const { - return INTERFACE_ID_PPB_CONTEXT_3D; -} - bool PPB_Context3D_Proxy::OnMessageReceived(const IPC::Message& msg) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(PPB_Context3D_Proxy, msg) diff --git a/ppapi/proxy/ppb_context_3d_proxy.h b/ppapi/proxy/ppb_context_3d_proxy.h index 47b8146..117dbe0 100644 --- a/ppapi/proxy/ppb_context_3d_proxy.h +++ b/ppapi/proxy/ppb_context_3d_proxy.h @@ -74,14 +74,14 @@ class PPB_Context3D_Proxy : public InterfaceProxy { PPB_Context3D_Proxy(Dispatcher* dispatcher, const void* target_interface); virtual ~PPB_Context3D_Proxy(); + static const Info* GetInfo(); + const PPB_Context3D_Dev* ppb_context_3d_target() const { return reinterpret_cast<const PPB_Context3D_Dev*>(target_interface()); } const PPB_Context3DTrusted_Dev* ppb_context_3d_trusted() const; // InterfaceProxy implementation. - virtual const void* GetSourceInterface() const; - virtual InterfaceID GetInterfaceId() const; virtual bool OnMessageReceived(const IPC::Message& msg); private: diff --git a/ppapi/proxy/ppb_core_proxy.cc b/ppapi/proxy/ppb_core_proxy.cc index a9486c8..34993fa 100644 --- a/ppapi/proxy/ppb_core_proxy.cc +++ b/ppapi/proxy/ppb_core_proxy.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -79,6 +79,11 @@ const PPB_Core core_interface = { &IsMainThread }; +InterfaceProxy* CreateCoreProxy(Dispatcher* dispatcher, + const void* target_interface) { + return new PPB_Core_Proxy(dispatcher, target_interface); +} + } // namespace PPB_Core_Proxy::PPB_Core_Proxy(Dispatcher* dispatcher, @@ -89,12 +94,16 @@ PPB_Core_Proxy::PPB_Core_Proxy(Dispatcher* dispatcher, PPB_Core_Proxy::~PPB_Core_Proxy() { } -const void* PPB_Core_Proxy::GetSourceInterface() const { - return &core_interface; -} - -InterfaceID PPB_Core_Proxy::GetInterfaceId() const { - return INTERFACE_ID_PPB_CORE; +// static +const InterfaceProxy::Info* PPB_Core_Proxy::GetInfo() { + static const Info info = { + &core_interface, + PPB_CORE_INTERFACE, + INTERFACE_ID_PPB_CORE, + false, + &CreateCoreProxy, + }; + return &info; } bool PPB_Core_Proxy::OnMessageReceived(const IPC::Message& msg) { diff --git a/ppapi/proxy/ppb_core_proxy.h b/ppapi/proxy/ppb_core_proxy.h index 0f8c58a..6ad8b31 100644 --- a/ppapi/proxy/ppb_core_proxy.h +++ b/ppapi/proxy/ppb_core_proxy.h @@ -21,13 +21,13 @@ class PPB_Core_Proxy : public InterfaceProxy { PPB_Core_Proxy(Dispatcher* dispatcher, const void* target_interface); virtual ~PPB_Core_Proxy(); + static const Info* GetInfo(); + const PPB_Core* ppb_core_target() const { return reinterpret_cast<const PPB_Core*>(target_interface()); } // InterfaceProxy implementation. - virtual const void* GetSourceInterface() const; - virtual InterfaceID GetInterfaceId() const; virtual bool OnMessageReceived(const IPC::Message& msg); private: diff --git a/ppapi/proxy/ppb_cursor_control_proxy.cc b/ppapi/proxy/ppb_cursor_control_proxy.cc index f1a89a2..74d0ecd 100644 --- a/ppapi/proxy/ppb_cursor_control_proxy.cc +++ b/ppapi/proxy/ppb_cursor_control_proxy.cc @@ -98,6 +98,11 @@ const PPB_CursorControl_Dev cursor_control_interface = { &CanLockCursor }; +InterfaceProxy* CreateCursorControlProxy(Dispatcher* dispatcher, + const void* target_interface) { + return new PPB_CursorControl_Proxy(dispatcher, target_interface); +} + } // namespace PPB_CursorControl_Proxy::PPB_CursorControl_Proxy(Dispatcher* dispatcher, @@ -108,12 +113,16 @@ PPB_CursorControl_Proxy::PPB_CursorControl_Proxy(Dispatcher* dispatcher, PPB_CursorControl_Proxy::~PPB_CursorControl_Proxy() { } -const void* PPB_CursorControl_Proxy::GetSourceInterface() const { - return &cursor_control_interface; -} - -InterfaceID PPB_CursorControl_Proxy::GetInterfaceId() const { - return INTERFACE_ID_PPB_CURSORCONTROL; +// static +const InterfaceProxy::Info* PPB_CursorControl_Proxy::GetInfo() { + static const Info info = { + &cursor_control_interface, + PPB_CURSOR_CONTROL_DEV_INTERFACE, + INTERFACE_ID_PPB_CURSORCONTROL, + false, + &CreateCursorControlProxy, + }; + return &info; } bool PPB_CursorControl_Proxy::OnMessageReceived(const IPC::Message& msg) { diff --git a/ppapi/proxy/ppb_cursor_control_proxy.h b/ppapi/proxy/ppb_cursor_control_proxy.h index 00f82ac..e04b435 100644 --- a/ppapi/proxy/ppb_cursor_control_proxy.h +++ b/ppapi/proxy/ppb_cursor_control_proxy.h @@ -23,13 +23,13 @@ class PPB_CursorControl_Proxy : public InterfaceProxy { PPB_CursorControl_Proxy(Dispatcher* dispatcher, const void* target_interface); virtual ~PPB_CursorControl_Proxy(); + static const Info* GetInfo(); + const PPB_CursorControl_Dev* ppb_cursor_control_target() const { return reinterpret_cast<const PPB_CursorControl_Dev*>(target_interface()); } // InterfaceProxy implementation. - virtual const void* GetSourceInterface() const; - virtual InterfaceID GetInterfaceId() const; virtual bool OnMessageReceived(const IPC::Message& msg); private: diff --git a/ppapi/proxy/ppb_flash_proxy.cc b/ppapi/proxy/ppb_flash_proxy.cc index 6ff1cb5..7b2e778 100644 --- a/ppapi/proxy/ppb_flash_proxy.cc +++ b/ppapi/proxy/ppb_flash_proxy.cc @@ -235,7 +235,7 @@ PP_Bool NavigateToURL(PP_Instance instance, return result; } -const PPB_Flash ppb_flash = { +const PPB_Flash flash_interface = { &SetInstanceAlwaysOnTop, &DrawGlyphs, &GetProxyForURL, @@ -249,6 +249,11 @@ const PPB_Flash ppb_flash = { &NavigateToURL, }; +InterfaceProxy* CreateFlashProxy(Dispatcher* dispatcher, + const void* target_interface) { + return new PPB_Flash_Proxy(dispatcher, target_interface); +} + } // namespace PPB_Flash_Proxy::PPB_Flash_Proxy(Dispatcher* dispatcher, @@ -259,12 +264,16 @@ PPB_Flash_Proxy::PPB_Flash_Proxy(Dispatcher* dispatcher, PPB_Flash_Proxy::~PPB_Flash_Proxy() { } -const void* PPB_Flash_Proxy::GetSourceInterface() const { - return &ppb_flash; -} - -InterfaceID PPB_Flash_Proxy::GetInterfaceId() const { - return INTERFACE_ID_PPB_FLASH; +// static +const InterfaceProxy::Info* PPB_Flash_Proxy::GetInfo() { + static const Info info = { + &flash_interface, + PPB_FLASH_INTERFACE, + INTERFACE_ID_PPB_FLASH, + true, + &CreateFlashProxy, + }; + return &info; } bool PPB_Flash_Proxy::OnMessageReceived(const IPC::Message& msg) { diff --git a/ppapi/proxy/ppb_flash_proxy.h b/ppapi/proxy/ppb_flash_proxy.h index 797dae8..1d66a68 100644 --- a/ppapi/proxy/ppb_flash_proxy.h +++ b/ppapi/proxy/ppb_flash_proxy.h @@ -28,13 +28,13 @@ class PPB_Flash_Proxy : public InterfaceProxy { PPB_Flash_Proxy(Dispatcher* dispatcher, const void* target_interface); virtual ~PPB_Flash_Proxy(); + static const Info* GetInfo(); + const PPB_Flash* ppb_flash_target() const { return static_cast<const PPB_Flash*>(target_interface()); } // InterfaceProxy implementation. - virtual const void* GetSourceInterface() const; - virtual InterfaceID GetInterfaceId() const; virtual bool OnMessageReceived(const IPC::Message& msg); private: diff --git a/ppapi/proxy/ppb_font_proxy.cc b/ppapi/proxy/ppb_font_proxy.cc index 26ca738..67c363f 100644 --- a/ppapi/proxy/ppb_font_proxy.cc +++ b/ppapi/proxy/ppb_font_proxy.cc @@ -185,7 +185,7 @@ int32_t PixelOffsetForCharacter(PP_Resource font_id, return result; } -const PPB_Font_Dev ppb_font_interface = { +const PPB_Font_Dev font_interface = { &Create, &IsFont, &Describe, @@ -195,6 +195,11 @@ const PPB_Font_Dev ppb_font_interface = { &PixelOffsetForCharacter }; +InterfaceProxy* CreateFontProxy(Dispatcher* dispatcher, + const void* target_interface) { + return new PPB_Font_Proxy(dispatcher, target_interface); +} + } // namespace PPB_Font_Proxy::PPB_Font_Proxy(Dispatcher* dispatcher, @@ -205,12 +210,16 @@ PPB_Font_Proxy::PPB_Font_Proxy(Dispatcher* dispatcher, PPB_Font_Proxy::~PPB_Font_Proxy() { } -const void* PPB_Font_Proxy::GetSourceInterface() const { - return &ppb_font_interface; -} - -InterfaceID PPB_Font_Proxy::GetInterfaceId() const { - return INTERFACE_ID_PPB_FONT; +// static +const InterfaceProxy::Info* PPB_Font_Proxy::GetInfo() { + static const Info info = { + &font_interface, + PPB_FONT_DEV_INTERFACE, + INTERFACE_ID_PPB_FONT, + false, + &CreateFontProxy, + }; + return &info; } bool PPB_Font_Proxy::OnMessageReceived(const IPC::Message& msg) { diff --git a/ppapi/proxy/ppb_font_proxy.h b/ppapi/proxy/ppb_font_proxy.h index 1afe36f..40f53d6 100644 --- a/ppapi/proxy/ppb_font_proxy.h +++ b/ppapi/proxy/ppb_font_proxy.h @@ -25,13 +25,13 @@ class PPB_Font_Proxy : public InterfaceProxy { PPB_Font_Proxy(Dispatcher* dispatcher, const void* target_interface); virtual ~PPB_Font_Proxy(); + static const Info* GetInfo(); + const PPB_Font_Dev* ppb_font_target() const { return static_cast<const PPB_Font_Dev*>(target_interface()); } // InterfaceProxy implementation. - virtual const void* GetSourceInterface() const; - virtual InterfaceID GetInterfaceId() const; virtual bool OnMessageReceived(const IPC::Message& msg); private: diff --git a/ppapi/proxy/ppb_fullscreen_proxy.cc b/ppapi/proxy/ppb_fullscreen_proxy.cc index 6ae1dca..19c9ead 100644 --- a/ppapi/proxy/ppb_fullscreen_proxy.cc +++ b/ppapi/proxy/ppb_fullscreen_proxy.cc @@ -35,11 +35,16 @@ PP_Bool SetFullscreen(PP_Instance instance, PP_Bool fullscreen) { return result; } -const PPB_Fullscreen_Dev ppb_fullscreen = { +const PPB_Fullscreen_Dev fullscreen_interface = { &IsFullscreen, &SetFullscreen }; +InterfaceProxy* CreateFullscreenProxy(Dispatcher* dispatcher, + const void* target_interface) { + return new PPB_Fullscreen_Proxy(dispatcher, target_interface); +} + } // namespace PPB_Fullscreen_Proxy::PPB_Fullscreen_Proxy(Dispatcher* dispatcher, @@ -50,12 +55,16 @@ PPB_Fullscreen_Proxy::PPB_Fullscreen_Proxy(Dispatcher* dispatcher, PPB_Fullscreen_Proxy::~PPB_Fullscreen_Proxy() { } -const void* PPB_Fullscreen_Proxy::GetSourceInterface() const { - return &ppb_fullscreen; -} - -InterfaceID PPB_Fullscreen_Proxy::GetInterfaceId() const { - return INTERFACE_ID_PPB_FULLSCREEN; +// static +const InterfaceProxy::Info* PPB_Fullscreen_Proxy::GetInfo() { + static const Info info = { + &fullscreen_interface, + PPB_FULLSCREEN_DEV_INTERFACE, + INTERFACE_ID_PPB_FULLSCREEN, + false, + &CreateFullscreenProxy, + }; + return &info; } bool PPB_Fullscreen_Proxy::OnMessageReceived(const IPC::Message& msg) { diff --git a/ppapi/proxy/ppb_fullscreen_proxy.h b/ppapi/proxy/ppb_fullscreen_proxy.h index 502d5b1..d68965a 100644 --- a/ppapi/proxy/ppb_fullscreen_proxy.h +++ b/ppapi/proxy/ppb_fullscreen_proxy.h @@ -20,13 +20,13 @@ class PPB_Fullscreen_Proxy : public InterfaceProxy { PPB_Fullscreen_Proxy(Dispatcher* dispatcher, const void* target_interface); virtual ~PPB_Fullscreen_Proxy(); + static const Info* GetInfo(); + const PPB_Fullscreen_Dev* ppb_fullscreen_target() const { return reinterpret_cast<const PPB_Fullscreen_Dev*>(target_interface()); } // InterfaceProxy implementation. - virtual const void* GetSourceInterface() const; - virtual InterfaceID GetInterfaceId() const; virtual bool OnMessageReceived(const IPC::Message& msg); private: diff --git a/ppapi/proxy/ppb_gles_chromium_texture_mapping_proxy.cc b/ppapi/proxy/ppb_gles_chromium_texture_mapping_proxy.cc index e8fdb27..b6e1b51 100644 --- a/ppapi/proxy/ppb_gles_chromium_texture_mapping_proxy.cc +++ b/ppapi/proxy/ppb_gles_chromium_texture_mapping_proxy.cc @@ -37,11 +37,17 @@ void UnmapTexSubImage2DCHROMIUM(PP_Resource context_id, const void* mem) { context->gles2_impl()->UnmapTexSubImage2DCHROMIUM(mem); } -const struct PPB_GLESChromiumTextureMapping_Dev ppb_gles2_chromium_tm = { +const struct PPB_GLESChromiumTextureMapping_Dev gles2_chromium_tm_interface = { MapTexSubImage2DCHROMIUM, UnmapTexSubImage2DCHROMIUM }; +InterfaceProxy* CreateGLESChromiumTextureMappingProxy( + Dispatcher* dispatcher, + const void* target_interface) { + return new PPB_GLESChromiumTextureMapping_Proxy(dispatcher, target_interface); +} + } // namespace PPB_GLESChromiumTextureMapping_Proxy::PPB_GLESChromiumTextureMapping_Proxy( @@ -53,12 +59,16 @@ PPB_GLESChromiumTextureMapping_Proxy::PPB_GLESChromiumTextureMapping_Proxy( PPB_GLESChromiumTextureMapping_Proxy::~PPB_GLESChromiumTextureMapping_Proxy() { } -const void* PPB_GLESChromiumTextureMapping_Proxy::GetSourceInterface() const { - return &ppb_gles2_chromium_tm; -} - -InterfaceID PPB_GLESChromiumTextureMapping_Proxy::GetInterfaceId() const { - return INTERFACE_ID_NONE; +// static +const InterfaceProxy::Info* PPB_GLESChromiumTextureMapping_Proxy::GetInfo() { + static const Info info = { + &gles2_chromium_tm_interface, + PPB_GLES_CHROMIUM_TEXTURE_MAPPING_DEV_INTERFACE, + INTERFACE_ID_PPB_GLES_CHROMIUM_TM, + false, + &CreateGLESChromiumTextureMappingProxy, + }; + return &info; } bool PPB_GLESChromiumTextureMapping_Proxy::OnMessageReceived( diff --git a/ppapi/proxy/ppb_gles_chromium_texture_mapping_proxy.h b/ppapi/proxy/ppb_gles_chromium_texture_mapping_proxy.h index eff9b4e..cff6c1e 100644 --- a/ppapi/proxy/ppb_gles_chromium_texture_mapping_proxy.h +++ b/ppapi/proxy/ppb_gles_chromium_texture_mapping_proxy.h @@ -18,6 +18,8 @@ class PPB_GLESChromiumTextureMapping_Proxy : public InterfaceProxy { const void* target_interface); virtual ~PPB_GLESChromiumTextureMapping_Proxy(); + static const Info* GetInfo(); + const PPB_GLESChromiumTextureMapping_Dev* ppb_gles_chromium_tm_target() const { return reinterpret_cast<const PPB_GLESChromiumTextureMapping_Dev*>( @@ -25,8 +27,6 @@ class PPB_GLESChromiumTextureMapping_Proxy : public InterfaceProxy { } // InterfaceProxy implementation. - virtual const void* GetSourceInterface() const; - virtual InterfaceID GetInterfaceId() const; virtual bool OnMessageReceived(const IPC::Message& msg); }; diff --git a/ppapi/proxy/ppb_graphics_2d_proxy.cc b/ppapi/proxy/ppb_graphics_2d_proxy.cc index be98e1d..4c488f9 100644 --- a/ppapi/proxy/ppb_graphics_2d_proxy.cc +++ b/ppapi/proxy/ppb_graphics_2d_proxy.cc @@ -189,7 +189,7 @@ int32_t Flush(PP_Resource graphics_2d, return PP_ERROR_WOULDBLOCK; } -const PPB_Graphics2D ppb_graphics_2d = { +const PPB_Graphics2D graphics_2d_interface = { &Create, &IsGraphics2D, &Describe, @@ -199,6 +199,11 @@ const PPB_Graphics2D ppb_graphics_2d = { &Flush }; +InterfaceProxy* CreateGraphics2DProxy(Dispatcher* dispatcher, + const void* target_interface) { + return new PPB_Graphics2D_Proxy(dispatcher, target_interface); +} + } // namespace PPB_Graphics2D_Proxy::PPB_Graphics2D_Proxy(Dispatcher* dispatcher, @@ -210,12 +215,16 @@ PPB_Graphics2D_Proxy::PPB_Graphics2D_Proxy(Dispatcher* dispatcher, PPB_Graphics2D_Proxy::~PPB_Graphics2D_Proxy() { } -const void* PPB_Graphics2D_Proxy::GetSourceInterface() const { - return &ppb_graphics_2d; -} - -InterfaceID PPB_Graphics2D_Proxy::GetInterfaceId() const { - return INTERFACE_ID_PPB_GRAPHICS_2D; +// static +const InterfaceProxy::Info* PPB_Graphics2D_Proxy::GetInfo() { + static const Info info = { + &graphics_2d_interface, + PPB_GRAPHICS_2D_INTERFACE, + INTERFACE_ID_PPB_GRAPHICS_2D, + false, + &CreateGraphics2DProxy, + }; + return &info; } bool PPB_Graphics2D_Proxy::OnMessageReceived(const IPC::Message& msg) { diff --git a/ppapi/proxy/ppb_graphics_2d_proxy.h b/ppapi/proxy/ppb_graphics_2d_proxy.h index 0e9400f..c98065d 100644 --- a/ppapi/proxy/ppb_graphics_2d_proxy.h +++ b/ppapi/proxy/ppb_graphics_2d_proxy.h @@ -29,13 +29,13 @@ class PPB_Graphics2D_Proxy : public InterfaceProxy { PPB_Graphics2D_Proxy(Dispatcher* dispatcher, const void* target_interface); virtual ~PPB_Graphics2D_Proxy(); + static const Info* GetInfo(); + const PPB_Graphics2D* ppb_graphics_2d_target() const { return static_cast<const PPB_Graphics2D*>(target_interface()); } // InterfaceProxy implementation. - virtual const void* GetSourceInterface() const; - virtual InterfaceID GetInterfaceId() const; virtual bool OnMessageReceived(const IPC::Message& msg); private: diff --git a/ppapi/proxy/ppb_image_data_proxy.cc b/ppapi/proxy/ppb_image_data_proxy.cc index 18b4614..a38b620 100644 --- a/ppapi/proxy/ppb_image_data_proxy.cc +++ b/ppapi/proxy/ppb_image_data_proxy.cc @@ -198,7 +198,7 @@ void Unmap(PP_Resource resource) { object->Unmap(); } -const PPB_ImageData ppb_imagedata = { +const PPB_ImageData image_data_interface = { &GetNativeImageDataFormat, &IsImageDataFormatSupported, &Create, @@ -208,6 +208,11 @@ const PPB_ImageData ppb_imagedata = { &Unmap, }; +InterfaceProxy* CreateImageDataProxy(Dispatcher* dispatcher, + const void* target_interface) { + return new PPB_ImageData_Proxy(dispatcher, target_interface); +} + } // namespace PPB_ImageData_Proxy::PPB_ImageData_Proxy(Dispatcher* dispatcher, @@ -218,12 +223,16 @@ PPB_ImageData_Proxy::PPB_ImageData_Proxy(Dispatcher* dispatcher, PPB_ImageData_Proxy::~PPB_ImageData_Proxy() { } -const void* PPB_ImageData_Proxy::GetSourceInterface() const { - return &ppb_imagedata; -} - -InterfaceID PPB_ImageData_Proxy::GetInterfaceId() const { - return INTERFACE_ID_PPB_IMAGE_DATA; +// static +const InterfaceProxy::Info* PPB_ImageData_Proxy::GetInfo() { + static const Info info = { + &image_data_interface, + PPB_IMAGEDATA_INTERFACE, + INTERFACE_ID_PPB_IMAGE_DATA, + false, + &CreateImageDataProxy, + }; + return &info; } bool PPB_ImageData_Proxy::OnMessageReceived(const IPC::Message& msg) { diff --git a/ppapi/proxy/ppb_image_data_proxy.h b/ppapi/proxy/ppb_image_data_proxy.h index 62f83fd..70632cb 100644 --- a/ppapi/proxy/ppb_image_data_proxy.h +++ b/ppapi/proxy/ppb_image_data_proxy.h @@ -27,13 +27,13 @@ class PPB_ImageData_Proxy : public InterfaceProxy { PPB_ImageData_Proxy(Dispatcher* dispatcher, const void* target_interface); virtual ~PPB_ImageData_Proxy(); + static const Info* GetInfo(); + const PPB_ImageData* ppb_image_data_target() const { return static_cast<const PPB_ImageData*>(target_interface()); } // InterfaceProxy implementation. - virtual const void* GetSourceInterface() const; - virtual InterfaceID GetInterfaceId() const; virtual bool OnMessageReceived(const IPC::Message& msg); private: diff --git a/ppapi/proxy/ppb_instance_proxy.cc b/ppapi/proxy/ppb_instance_proxy.cc index d17e17b..76ac13e 100644 --- a/ppapi/proxy/ppb_instance_proxy.cc +++ b/ppapi/proxy/ppb_instance_proxy.cc @@ -91,6 +91,11 @@ const PPB_Instance instance_interface = { &ExecuteScript }; +InterfaceProxy* CreateInstanceProxy(Dispatcher* dispatcher, + const void* target_interface) { + return new PPB_Instance_Proxy(dispatcher, target_interface); +} + } // namespace PPB_Instance_Proxy::PPB_Instance_Proxy(Dispatcher* dispatcher, @@ -101,12 +106,16 @@ PPB_Instance_Proxy::PPB_Instance_Proxy(Dispatcher* dispatcher, PPB_Instance_Proxy::~PPB_Instance_Proxy() { } -const void* PPB_Instance_Proxy::GetSourceInterface() const { - return &instance_interface; -} - -InterfaceID PPB_Instance_Proxy::GetInterfaceId() const { - return INTERFACE_ID_PPB_INSTANCE; +// static +const InterfaceProxy::Info* PPB_Instance_Proxy::GetInfo() { + static const Info info = { + &instance_interface, + PPB_INSTANCE_INTERFACE, + INTERFACE_ID_PPB_INSTANCE, + false, + &CreateInstanceProxy, + }; + return &info; } bool PPB_Instance_Proxy::OnMessageReceived(const IPC::Message& msg) { diff --git a/ppapi/proxy/ppb_instance_proxy.h b/ppapi/proxy/ppb_instance_proxy.h index 4a73d5c..e90e518 100644 --- a/ppapi/proxy/ppb_instance_proxy.h +++ b/ppapi/proxy/ppb_instance_proxy.h @@ -25,13 +25,13 @@ class PPB_Instance_Proxy : public InterfaceProxy { PPB_Instance_Proxy(Dispatcher* dispatcher, const void* target_interface); virtual ~PPB_Instance_Proxy(); + static const Info* GetInfo(); + const PPB_Instance* ppb_instance_target() const { return reinterpret_cast<const PPB_Instance*>(target_interface()); } // InterfaceProxy implementation. - virtual const void* GetSourceInterface() const; - virtual InterfaceID GetInterfaceId() const; virtual bool OnMessageReceived(const IPC::Message& msg); private: diff --git a/ppapi/proxy/ppb_opengles2_proxy.cc b/ppapi/proxy/ppb_opengles2_proxy.cc index 51a8d13..4de1730 100644 --- a/ppapi/proxy/ppb_opengles2_proxy.cc +++ b/ppapi/proxy/ppb_opengles2_proxy.cc @@ -866,7 +866,7 @@ void Viewport( context->gles2_impl()->Viewport(x, y, width, height); } -const struct PPB_OpenGLES2_Dev ppb_opengles2 = { +const struct PPB_OpenGLES2_Dev opengles2_interface = { &ActiveTexture, &AttachShader, &BindAttribLocation, @@ -1011,6 +1011,12 @@ const struct PPB_OpenGLES2_Dev ppb_opengles2 = { &Viewport }; + +InterfaceProxy* CreateOpenGLES2Proxy(Dispatcher* dispatcher, + const void* target_interface) { + return new PPB_OpenGLES2_Proxy(dispatcher, target_interface); +} + } // namespace PPB_OpenGLES2_Proxy::PPB_OpenGLES2_Proxy(Dispatcher* dispatcher, @@ -1021,12 +1027,16 @@ PPB_OpenGLES2_Proxy::PPB_OpenGLES2_Proxy(Dispatcher* dispatcher, PPB_OpenGLES2_Proxy::~PPB_OpenGLES2_Proxy() { } -const void* PPB_OpenGLES2_Proxy::GetSourceInterface() const { - return &ppb_opengles2; -} - -InterfaceID PPB_OpenGLES2_Proxy::GetInterfaceId() const { - return INTERFACE_ID_NONE; +// static +const InterfaceProxy::Info* PPB_OpenGLES2_Proxy::GetInfo() { + static const Info info = { + &opengles2_interface, + PPB_OPENGLES2_DEV_INTERFACE, + INTERFACE_ID_PPB_OPENGLES2, + false, + &CreateOpenGLES2Proxy, + }; + return &info; } bool PPB_OpenGLES2_Proxy::OnMessageReceived(const IPC::Message& msg) { diff --git a/ppapi/proxy/ppb_opengles2_proxy.h b/ppapi/proxy/ppb_opengles2_proxy.h index 5901b4c..d4ea6f9 100644 --- a/ppapi/proxy/ppb_opengles2_proxy.h +++ b/ppapi/proxy/ppb_opengles2_proxy.h @@ -17,13 +17,13 @@ class PPB_OpenGLES2_Proxy : public InterfaceProxy { PPB_OpenGLES2_Proxy(Dispatcher* dispatcher, const void* target_interface); virtual ~PPB_OpenGLES2_Proxy(); + static const Info* GetInfo(); + const PPB_OpenGLES2_Dev* ppb_gles2_target() const { return reinterpret_cast<const PPB_OpenGLES2_Dev*>(target_interface()); } // InterfaceProxy implementation. - virtual const void* GetSourceInterface() const; - virtual InterfaceID GetInterfaceId() const; virtual bool OnMessageReceived(const IPC::Message& msg); private: diff --git a/ppapi/proxy/ppb_pdf_proxy.cc b/ppapi/proxy/ppb_pdf_proxy.cc index e3c656f..b7e0744 100644 --- a/ppapi/proxy/ppb_pdf_proxy.cc +++ b/ppapi/proxy/ppb_pdf_proxy.cc @@ -107,13 +107,18 @@ bool GetFontTableForPrivateFontFile(PP_Resource font_file, return true; } -const PPB_PDF ppb_pdf = { +const PPB_PDF pdf_interface = { NULL, // &GetLocalizedString, NULL, // &GetResourceImage, &GetFontFileWithFallback, &GetFontTableForPrivateFontFile, }; +InterfaceProxy* CreatePDFProxy(Dispatcher* dispatcher, + const void* target_interface) { + return new PPB_PDF_Proxy(dispatcher, target_interface); +} + } // namespace PPB_PDF_Proxy::PPB_PDF_Proxy(Dispatcher* dispatcher, @@ -124,12 +129,16 @@ PPB_PDF_Proxy::PPB_PDF_Proxy(Dispatcher* dispatcher, PPB_PDF_Proxy::~PPB_PDF_Proxy() { } -const void* PPB_PDF_Proxy::GetSourceInterface() const { - return &ppb_pdf; -} - -InterfaceID PPB_PDF_Proxy::GetInterfaceId() const { - return INTERFACE_ID_PPB_PDF; +// static +const InterfaceProxy::Info* PPB_PDF_Proxy::GetInfo() { + static const Info info = { + &pdf_interface, + PPB_PDF_INTERFACE, + INTERFACE_ID_PPB_PDF, + true, + &CreatePDFProxy, + }; + return &info; } bool PPB_PDF_Proxy::OnMessageReceived(const IPC::Message& msg) { diff --git a/ppapi/proxy/ppb_pdf_proxy.h b/ppapi/proxy/ppb_pdf_proxy.h index c0da291..dbafd2d 100644 --- a/ppapi/proxy/ppb_pdf_proxy.h +++ b/ppapi/proxy/ppb_pdf_proxy.h @@ -21,13 +21,13 @@ class PPB_PDF_Proxy : public InterfaceProxy { PPB_PDF_Proxy(Dispatcher* dispatcher, const void* target_interface); virtual ~PPB_PDF_Proxy(); + static const Info* GetInfo(); + const PPB_PDF* ppb_pdf_target() const { return static_cast<const PPB_PDF*>(target_interface()); } // InterfaceProxy implementation. - virtual const void* GetSourceInterface() const; - virtual InterfaceID GetInterfaceId() const; virtual bool OnMessageReceived(const IPC::Message& msg); private: diff --git a/ppapi/proxy/ppb_surface_3d_proxy.cc b/ppapi/proxy/ppb_surface_3d_proxy.cc index eaca110..fc97c46 100644 --- a/ppapi/proxy/ppb_surface_3d_proxy.cc +++ b/ppapi/proxy/ppb_surface_3d_proxy.cc @@ -98,7 +98,7 @@ int32_t SwapBuffers(PP_Resource surface_id, return PP_ERROR_WOULDBLOCK; } -const PPB_Surface3D_Dev ppb_surface_3d = { +const PPB_Surface3D_Dev surface_3d_interface = { &Create, &IsSurface3D, &SetAttrib, @@ -106,6 +106,11 @@ const PPB_Surface3D_Dev ppb_surface_3d = { &SwapBuffers }; +InterfaceProxy* CreateSurface3DProxy(Dispatcher* dispatcher, + const void* target_interface) { + return new PPB_Surface3D_Proxy(dispatcher, target_interface); +} + } // namespace PPB_Surface3D_Proxy::PPB_Surface3D_Proxy(Dispatcher* dispatcher, @@ -117,12 +122,16 @@ PPB_Surface3D_Proxy::PPB_Surface3D_Proxy(Dispatcher* dispatcher, PPB_Surface3D_Proxy::~PPB_Surface3D_Proxy() { } -const void* PPB_Surface3D_Proxy::GetSourceInterface() const { - return &ppb_surface_3d; -} - -InterfaceID PPB_Surface3D_Proxy::GetInterfaceId() const { - return INTERFACE_ID_PPB_SURFACE_3D; +// static +const InterfaceProxy::Info* PPB_Surface3D_Proxy::GetInfo() { + static const Info info = { + &surface_3d_interface, + PPB_SURFACE_3D_DEV_INTERFACE, + INTERFACE_ID_PPB_SURFACE_3D, + false, + &CreateSurface3DProxy, + }; + return &info; } bool PPB_Surface3D_Proxy::OnMessageReceived(const IPC::Message& msg) { diff --git a/ppapi/proxy/ppb_surface_3d_proxy.h b/ppapi/proxy/ppb_surface_3d_proxy.h index 2bd4f83..70054bd 100644 --- a/ppapi/proxy/ppb_surface_3d_proxy.h +++ b/ppapi/proxy/ppb_surface_3d_proxy.h @@ -68,13 +68,13 @@ class PPB_Surface3D_Proxy : public InterfaceProxy { PPB_Surface3D_Proxy(Dispatcher* dispatcher, const void* target_interface); virtual ~PPB_Surface3D_Proxy(); + static const Info* GetInfo(); + const PPB_Surface3D_Dev* ppb_surface_3d_target() const { return reinterpret_cast<const PPB_Surface3D_Dev*>(target_interface()); } // InterfaceProxy implementation. - virtual const void* GetSourceInterface() const; - virtual InterfaceID GetInterfaceId() const; virtual bool OnMessageReceived(const IPC::Message& msg); private: diff --git a/ppapi/proxy/ppb_testing_proxy.cc b/ppapi/proxy/ppb_testing_proxy.cc index b65bae7..ca15151 100644 --- a/ppapi/proxy/ppb_testing_proxy.cc +++ b/ppapi/proxy/ppb_testing_proxy.cc @@ -70,6 +70,11 @@ const PPB_Testing_Dev testing_interface = { &GetLiveObjectsForInstance }; +InterfaceProxy* CreateTestingProxy(Dispatcher* dispatcher, + const void* target_interface) { + return new PPB_Testing_Proxy(dispatcher, target_interface); +} + } // namespace PPB_Testing_Proxy::PPB_Testing_Proxy(Dispatcher* dispatcher, @@ -80,12 +85,16 @@ PPB_Testing_Proxy::PPB_Testing_Proxy(Dispatcher* dispatcher, PPB_Testing_Proxy::~PPB_Testing_Proxy() { } -const void* PPB_Testing_Proxy::GetSourceInterface() const { - return &testing_interface; -} - -InterfaceID PPB_Testing_Proxy::GetInterfaceId() const { - return INTERFACE_ID_PPB_TESTING; +// static +const InterfaceProxy::Info* PPB_Testing_Proxy::GetInfo() { + static const Info info = { + &testing_interface, + PPB_TESTING_DEV_INTERFACE, + INTERFACE_ID_PPB_TESTING, + false, + &CreateTestingProxy, + }; + return &info; } bool PPB_Testing_Proxy::OnMessageReceived(const IPC::Message& msg) { diff --git a/ppapi/proxy/ppb_testing_proxy.h b/ppapi/proxy/ppb_testing_proxy.h index 9133a2d..ed938f1 100644 --- a/ppapi/proxy/ppb_testing_proxy.h +++ b/ppapi/proxy/ppb_testing_proxy.h @@ -22,13 +22,13 @@ class PPB_Testing_Proxy : public InterfaceProxy { PPB_Testing_Proxy(Dispatcher* dispatcher, const void* target_interface); virtual ~PPB_Testing_Proxy(); + static const Info* GetInfo(); + const PPB_Testing_Dev* ppb_testing_target() const { return static_cast<const PPB_Testing_Dev*>(target_interface()); } // InterfaceProxy implementation. - virtual const void* GetSourceInterface() const; - virtual InterfaceID GetInterfaceId() const; virtual bool OnMessageReceived(const IPC::Message& msg); private: diff --git a/ppapi/proxy/ppb_url_loader_proxy.cc b/ppapi/proxy/ppb_url_loader_proxy.cc index e2786b6..a021eff 100644 --- a/ppapi/proxy/ppb_url_loader_proxy.cc +++ b/ppapi/proxy/ppb_url_loader_proxy.cc @@ -246,7 +246,7 @@ void Close(PP_Resource loader_id) { INTERFACE_ID_PPB_URL_LOADER, loader_object->host_resource())); } -const PPB_URLLoader ppb_urlloader = { +const PPB_URLLoader urlloader_interface = { &Create, &IsURLLoader, &Open, @@ -259,6 +259,11 @@ const PPB_URLLoader ppb_urlloader = { &Close }; +InterfaceProxy* CreateURLLoaderProxy(Dispatcher* dispatcher, + const void* target_interface) { + return new PPB_URLLoader_Proxy(dispatcher, target_interface); +} + // Plugin URLLoaderTrusted implementation -------------------------------------- void GrantUniversalAccess(PP_Resource loader_id) { @@ -272,11 +277,16 @@ void GrantUniversalAccess(PP_Resource loader_id) { INTERFACE_ID_PPB_URL_LOADER_TRUSTED, loader_object->host_resource())); } -const PPB_URLLoaderTrusted ppb_urlloader_trusted = { +const PPB_URLLoaderTrusted urlloader_trusted_interface = { &GrantUniversalAccess, NULL, // RegisterStatusCallback is used internally by the proxy only. }; +InterfaceProxy* CreateURLLoaderTrustedProxy(Dispatcher* dispatcher, + const void* target_interface) { + return new PPB_URLLoaderTrusted_Proxy(dispatcher, target_interface); +} + } // namespace // PPB_URLLoader_Proxy --------------------------------------------------------- @@ -302,12 +312,16 @@ PP_Resource PPB_URLLoader_Proxy::TrackPluginResource( return PluginResourceTracker::GetInstance()->AddResource(object); } -const void* PPB_URLLoader_Proxy::GetSourceInterface() const { - return &ppb_urlloader; -} - -InterfaceID PPB_URLLoader_Proxy::GetInterfaceId() const { - return INTERFACE_ID_PPB_URL_LOADER; +// static +const InterfaceProxy::Info* PPB_URLLoader_Proxy::GetInfo() { + static const Info info = { + &urlloader_interface, + PPB_URLLOADER_INTERFACE, + INTERFACE_ID_PPB_URL_LOADER, + false, + &CreateURLLoaderProxy, + }; + return &info; } bool PPB_URLLoader_Proxy::OnMessageReceived(const IPC::Message& msg) { @@ -490,12 +504,16 @@ PPB_URLLoaderTrusted_Proxy::PPB_URLLoaderTrusted_Proxy( PPB_URLLoaderTrusted_Proxy::~PPB_URLLoaderTrusted_Proxy() { } -const void* PPB_URLLoaderTrusted_Proxy::GetSourceInterface() const { - return &ppb_urlloader_trusted; -} - -InterfaceID PPB_URLLoaderTrusted_Proxy::GetInterfaceId() const { - return INTERFACE_ID_PPB_URL_LOADER_TRUSTED; +// static +const InterfaceProxy::Info* PPB_URLLoaderTrusted_Proxy::GetInfo() { + static const Info info = { + &urlloader_trusted_interface, + PPB_URLLOADERTRUSTED_INTERFACE, + INTERFACE_ID_PPB_URL_LOADER_TRUSTED, + true, + &CreateURLLoaderTrustedProxy, + }; + return &info; } bool PPB_URLLoaderTrusted_Proxy::OnMessageReceived(const IPC::Message& msg) { diff --git a/ppapi/proxy/ppb_url_loader_proxy.h b/ppapi/proxy/ppb_url_loader_proxy.h index 49f49ea..523488b 100644 --- a/ppapi/proxy/ppb_url_loader_proxy.h +++ b/ppapi/proxy/ppb_url_loader_proxy.h @@ -29,6 +29,8 @@ class PPB_URLLoader_Proxy : public InterfaceProxy { PPB_URLLoader_Proxy(Dispatcher* dispatcher, const void* target_interface); virtual ~PPB_URLLoader_Proxy(); + static const Info* GetInfo(); + // URLLoader objects are normally allocated by the Create function, but // they are also provided to PPP_Instance.OnMsgHandleDocumentLoad. This // function allows the proxy for DocumentLoad to create the correct plugin @@ -41,8 +43,6 @@ class PPB_URLLoader_Proxy : public InterfaceProxy { } // InterfaceProxy implementation. - virtual const void* GetSourceInterface() const; - virtual InterfaceID GetInterfaceId() const; virtual bool OnMessageReceived(const IPC::Message& msg); private: @@ -86,13 +86,13 @@ class PPB_URLLoaderTrusted_Proxy : public InterfaceProxy { const void* target_interface); virtual ~PPB_URLLoaderTrusted_Proxy(); + static const Info* GetInfo(); + const PPB_URLLoaderTrusted* ppb_url_loader_trusted_target() const { return reinterpret_cast<const PPB_URLLoaderTrusted*>(target_interface()); } // InterfaceProxy implementation. - virtual const void* GetSourceInterface() const; - virtual InterfaceID GetInterfaceId() const; virtual bool OnMessageReceived(const IPC::Message& msg); private: diff --git a/ppapi/proxy/ppb_url_request_info_proxy.cc b/ppapi/proxy/ppb_url_request_info_proxy.cc index ecd7c3d..385f13a 100644 --- a/ppapi/proxy/ppb_url_request_info_proxy.cc +++ b/ppapi/proxy/ppb_url_request_info_proxy.cc @@ -118,7 +118,7 @@ PP_Bool AppendFileToBody(PP_Resource request_id, return PP_TRUE; } -const PPB_URLRequestInfo ppb_urlrequestinfo = { +const PPB_URLRequestInfo urlrequestinfo_interface = { &Create, &IsURLRequestInfo, &SetProperty, @@ -126,6 +126,11 @@ const PPB_URLRequestInfo ppb_urlrequestinfo = { &AppendFileToBody }; +InterfaceProxy* CreateURLRequestInfoProxy(Dispatcher* dispatcher, + const void* target_interface) { + return new PPB_URLRequestInfo_Proxy(dispatcher, target_interface); +} + } // namespace PPB_URLRequestInfo_Proxy::PPB_URLRequestInfo_Proxy( @@ -137,12 +142,16 @@ PPB_URLRequestInfo_Proxy::PPB_URLRequestInfo_Proxy( PPB_URLRequestInfo_Proxy::~PPB_URLRequestInfo_Proxy() { } -const void* PPB_URLRequestInfo_Proxy::GetSourceInterface() const { - return &ppb_urlrequestinfo; -} - -InterfaceID PPB_URLRequestInfo_Proxy::GetInterfaceId() const { - return INTERFACE_ID_PPB_URL_REQUEST_INFO; +// static +const InterfaceProxy::Info* PPB_URLRequestInfo_Proxy::GetInfo() { + static const Info info = { + &urlrequestinfo_interface, + PPB_URLREQUESTINFO_INTERFACE, + INTERFACE_ID_PPB_URL_REQUEST_INFO, + false, + &CreateURLRequestInfoProxy, + }; + return &info; } bool PPB_URLRequestInfo_Proxy::OnMessageReceived(const IPC::Message& msg) { diff --git a/ppapi/proxy/ppb_url_request_info_proxy.h b/ppapi/proxy/ppb_url_request_info_proxy.h index bfd4dba..aea077f 100644 --- a/ppapi/proxy/ppb_url_request_info_proxy.h +++ b/ppapi/proxy/ppb_url_request_info_proxy.h @@ -24,13 +24,13 @@ class PPB_URLRequestInfo_Proxy : public InterfaceProxy { const void* target_interface); virtual ~PPB_URLRequestInfo_Proxy(); + static const Info* GetInfo(); + const PPB_URLRequestInfo* ppb_url_request_info_target() const { return static_cast<const PPB_URLRequestInfo*>(target_interface()); } // InterfaceProxy implementation. - virtual const void* GetSourceInterface() const; - virtual InterfaceID GetInterfaceId() const; virtual bool OnMessageReceived(const IPC::Message& msg); private: diff --git a/ppapi/proxy/ppb_url_response_info_proxy.cc b/ppapi/proxy/ppb_url_response_info_proxy.cc index 9de374d..8e12470 100644 --- a/ppapi/proxy/ppb_url_response_info_proxy.cc +++ b/ppapi/proxy/ppb_url_response_info_proxy.cc @@ -60,12 +60,17 @@ PP_Resource GetBodyAsFileRef(PP_Resource response) { return 0; } -const PPB_URLResponseInfo ppb_urlresponseinfo = { +const PPB_URLResponseInfo urlresponseinfo_interface = { &IsURLResponseInfo, &GetProperty, &GetBodyAsFileRef }; +InterfaceProxy* CreateURLResponseInfoProxy(Dispatcher* dispatcher, + const void* target_interface) { + return new PPB_URLResponseInfo_Proxy(dispatcher, target_interface); +} + } // namespace PPB_URLResponseInfo_Proxy::PPB_URLResponseInfo_Proxy( @@ -78,20 +83,24 @@ PPB_URLResponseInfo_Proxy::~PPB_URLResponseInfo_Proxy() { } // static +const InterfaceProxy::Info* PPB_URLResponseInfo_Proxy::GetInfo() { + static const Info info = { + &urlresponseinfo_interface, + PPB_URLRESPONSEINFO_INTERFACE, + INTERFACE_ID_PPB_URL_RESPONSE_INFO, + false, + &CreateURLResponseInfoProxy, + }; + return &info; +} + +// static PP_Resource PPB_URLResponseInfo_Proxy::CreateResponseForResource( const HostResource& resource) { linked_ptr<URLResponseInfo> object(new URLResponseInfo(resource)); return PluginResourceTracker::GetInstance()->AddResource(object); } -const void* PPB_URLResponseInfo_Proxy::GetSourceInterface() const { - return &ppb_urlresponseinfo; -} - -InterfaceID PPB_URLResponseInfo_Proxy::GetInterfaceId() const { - return INTERFACE_ID_PPB_URL_RESPONSE_INFO; -} - bool PPB_URLResponseInfo_Proxy::OnMessageReceived(const IPC::Message& msg) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(PPB_URLResponseInfo_Proxy, msg) diff --git a/ppapi/proxy/ppb_url_response_info_proxy.h b/ppapi/proxy/ppb_url_response_info_proxy.h index 0e1307f..50da19e 100644 --- a/ppapi/proxy/ppb_url_response_info_proxy.h +++ b/ppapi/proxy/ppb_url_response_info_proxy.h @@ -25,6 +25,8 @@ class PPB_URLResponseInfo_Proxy : public InterfaceProxy { const void* target_interface); virtual ~PPB_URLResponseInfo_Proxy(); + static const Info* GetInfo(); + // URLResponseInfo objects are actually created and returned by the // URLLoader. This function allows the URLLoader to convert a new // HostResource representing a response info to a properly tracked @@ -37,8 +39,6 @@ class PPB_URLResponseInfo_Proxy : public InterfaceProxy { } // InterfaceProxy implementation. - virtual const void* GetSourceInterface() const; - virtual InterfaceID GetInterfaceId() const; virtual bool OnMessageReceived(const IPC::Message& msg); private: diff --git a/ppapi/proxy/ppb_var_deprecated_proxy.cc b/ppapi/proxy/ppb_var_deprecated_proxy.cc index 665f24d..99e7ced 100644 --- a/ppapi/proxy/ppb_var_deprecated_proxy.cc +++ b/ppapi/proxy/ppb_var_deprecated_proxy.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -11,6 +11,7 @@ #include "ppapi/c/pp_var.h" #include "ppapi/c/ppb_core.h" #include "ppapi/proxy/plugin_dispatcher.h" +#include "ppapi/proxy/plugin_var_tracker.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/ppp_class_proxy.h" #include "ppapi/proxy/serialized_var.h" @@ -20,6 +21,32 @@ namespace proxy { namespace { +// Used to do get the set-up information for calling a var object. If the +// exception is set, returns NULL. Otherwise, computes the dispatcher for the +// given var object. If the var is not a valid object, returns NULL and sets +// the exception. +PluginDispatcher* CheckExceptionAndGetDispatcher(const PP_Var& object, + PP_Var* exception) { + // If an exception is already set, we don't need to do anything, just return + // an error to the caller. + if (exception && exception->type != PP_VARTYPE_UNDEFINED) + return NULL; + + PluginVarTracker* tracker = PluginVarTracker::GetInstance(); + PluginDispatcher* dispatcher = tracker->DispatcherForPluginObject(object); + if (dispatcher) + return dispatcher; + + // The object is invalid. This means we can't figure out which dispatcher + // to use, which is OK because the call will fail anyway. Set the exception. + if (exception) { + exception->type = PP_VARTYPE_STRING; + exception->value.as_id = + tracker->MakeString("Attempting to use an invalid object"); + } + return NULL; +} + // PPP_Var_Deprecated plugin --------------------------------------------------- void AddRefVar(PP_Var var) { @@ -52,7 +79,10 @@ const char* VarToUtf8(PP_Var var, uint32_t* len) { bool HasProperty(PP_Var var, PP_Var name, PP_Var* exception) { - Dispatcher* dispatcher = PluginDispatcher::Get(); + Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(var, exception); + if (!dispatcher) + return false; + ReceiveSerializedException se(dispatcher, exception); PP_Bool result = PP_FALSE; if (!se.IsThrown()) { @@ -67,7 +97,10 @@ bool HasProperty(PP_Var var, bool HasMethod(PP_Var var, PP_Var name, PP_Var* exception) { - Dispatcher* dispatcher = PluginDispatcher::Get(); + Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(var, exception); + if (!dispatcher) + return false; + ReceiveSerializedException se(dispatcher, exception); PP_Bool result = PP_FALSE; if (!se.IsThrown()) { @@ -82,7 +115,10 @@ bool HasMethod(PP_Var var, PP_Var GetProperty(PP_Var var, PP_Var name, PP_Var* exception) { - Dispatcher* dispatcher = PluginDispatcher::Get(); + Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(var, exception); + if (!dispatcher) + return PP_MakeUndefined(); + ReceiveSerializedException se(dispatcher, exception); ReceiveSerializedVarReturnValue result; if (!se.IsThrown()) { @@ -98,7 +134,12 @@ void EnumerateProperties(PP_Var var, uint32_t* property_count, PP_Var** properties, PP_Var* exception) { - Dispatcher* dispatcher = PluginDispatcher::Get(); + Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(var, exception); + if (!dispatcher) { + *property_count = 0; + *properties = NULL; + return; + } ReceiveSerializedVarVectorOutParam out_vector(dispatcher, property_count, properties); @@ -115,7 +156,10 @@ void SetProperty(PP_Var var, PP_Var name, PP_Var value, PP_Var* exception) { - Dispatcher* dispatcher = PluginDispatcher::Get(); + Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(var, exception); + if (!dispatcher) + return; + ReceiveSerializedException se(dispatcher, exception); if (!se.IsThrown()) { dispatcher->Send(new PpapiHostMsg_PPBVar_SetPropertyDeprecated( @@ -129,7 +173,10 @@ void SetProperty(PP_Var var, void RemoveProperty(PP_Var var, PP_Var name, PP_Var* exception) { - Dispatcher* dispatcher = PluginDispatcher::Get(); + Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(var, exception); + if (!dispatcher) + return; + ReceiveSerializedException se(dispatcher, exception); PP_Bool result = PP_FALSE; if (!se.IsThrown()) { @@ -145,7 +192,10 @@ PP_Var Call(PP_Var object, uint32_t argc, PP_Var* argv, PP_Var* exception) { - Dispatcher* dispatcher = PluginDispatcher::Get(); + Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(object, exception); + if (!dispatcher) + return PP_MakeUndefined(); + ReceiveSerializedVarReturnValue result; ReceiveSerializedException se(dispatcher, exception); if (!se.IsThrown()) { @@ -165,7 +215,10 @@ PP_Var Construct(PP_Var object, uint32_t argc, PP_Var* argv, PP_Var* exception) { - Dispatcher* dispatcher = PluginDispatcher::Get(); + Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(object, exception); + if (!dispatcher) + return PP_MakeUndefined(); + ReceiveSerializedVarReturnValue result; ReceiveSerializedException se(dispatcher, exception); if (!se.IsThrown()) { @@ -181,10 +234,13 @@ PP_Var Construct(PP_Var object, } bool IsInstanceOf(PP_Var var, - const PPP_Class_Deprecated* ppp_class, - void** ppp_class_data) { + const PPP_Class_Deprecated* ppp_class, + void** ppp_class_data) { + Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(var, NULL); + if (!dispatcher) + return false; + PP_Bool result = PP_FALSE; - Dispatcher* dispatcher = PluginDispatcher::Get(); int64 class_int = static_cast<int64>(reinterpret_cast<intptr_t>(ppp_class)); int64 class_data_int = 0; dispatcher->Send(new PpapiHostMsg_PPBVar_IsInstanceOfDeprecated( @@ -198,7 +254,10 @@ bool IsInstanceOf(PP_Var var, PP_Var CreateObject(PP_Instance instance, const PPP_Class_Deprecated* ppp_class, void* ppp_class_data) { - Dispatcher* dispatcher = PluginDispatcher::Get(); + Dispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); + if (!dispatcher) + return PP_MakeUndefined(); + ReceiveSerializedVarReturnValue result; int64 class_int = static_cast<int64>(reinterpret_cast<intptr_t>(ppp_class)); int64 data_int = @@ -226,6 +285,11 @@ const PPB_Var_Deprecated var_deprecated_interface = { &CreateObject }; +InterfaceProxy* CreateVarDeprecatedProxy(Dispatcher* dispatcher, + const void* target_interface) { + return new PPB_Var_Deprecated_Proxy(dispatcher, target_interface); +} + } // namespace PPB_Var_Deprecated_Proxy::PPB_Var_Deprecated_Proxy( @@ -237,12 +301,16 @@ PPB_Var_Deprecated_Proxy::PPB_Var_Deprecated_Proxy( PPB_Var_Deprecated_Proxy::~PPB_Var_Deprecated_Proxy() { } -const void* PPB_Var_Deprecated_Proxy::GetSourceInterface() const { - return &var_deprecated_interface; -} - -InterfaceID PPB_Var_Deprecated_Proxy::GetInterfaceId() const { - return INTERFACE_ID_PPB_VAR_DEPRECATED; +// static +const InterfaceProxy::Info* PPB_Var_Deprecated_Proxy::GetInfo() { + static const Info info = { + &var_deprecated_interface, + PPB_VAR_DEPRECATED_INTERFACE, + INTERFACE_ID_PPB_VAR_DEPRECATED, + false, + &CreateVarDeprecatedProxy, + }; + return &info; } bool PPB_Var_Deprecated_Proxy::OnMessageReceived(const IPC::Message& msg) { diff --git a/ppapi/proxy/ppb_var_deprecated_proxy.h b/ppapi/proxy/ppb_var_deprecated_proxy.h index 193da9d..d105d25 100644 --- a/ppapi/proxy/ppb_var_deprecated_proxy.h +++ b/ppapi/proxy/ppb_var_deprecated_proxy.h @@ -29,13 +29,13 @@ class PPB_Var_Deprecated_Proxy : public InterfaceProxy { const void* target_interface); virtual ~PPB_Var_Deprecated_Proxy(); + static const Info* GetInfo(); + const PPB_Var_Deprecated* ppb_var_target() const { return reinterpret_cast<const PPB_Var_Deprecated*>(target_interface()); } // InterfaceProxy implementation. - virtual const void* GetSourceInterface() const; - virtual InterfaceID GetInterfaceId() const; virtual bool OnMessageReceived(const IPC::Message& msg); private: diff --git a/ppapi/proxy/ppp_class_proxy.cc b/ppapi/proxy/ppp_class_proxy.cc index ab71565..0a020cc 100644 --- a/ppapi/proxy/ppp_class_proxy.cc +++ b/ppapi/proxy/ppp_class_proxy.cc @@ -192,14 +192,6 @@ PP_Var PPP_Class_Proxy::CreateProxiedObject(const PPB_Var_Deprecated* var, return var->CreateObject(module_id, &class_interface, object_proxy); } -const void* PPP_Class_Proxy::GetSourceInterface() const { - return &class_interface; -} - -InterfaceID PPP_Class_Proxy::GetInterfaceId() const { - return INTERFACE_ID_PPP_CLASS; -} - bool PPP_Class_Proxy::OnMessageReceived(const IPC::Message& msg) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(PPP_Class_Proxy, msg) diff --git a/ppapi/proxy/ppp_class_proxy.h b/ppapi/proxy/ppp_class_proxy.h index d4e2102..2cba23d 100644 --- a/ppapi/proxy/ppp_class_proxy.h +++ b/ppapi/proxy/ppp_class_proxy.h @@ -40,8 +40,6 @@ class PPP_Class_Proxy : public InterfaceProxy { int64 class_data); // InterfaceProxy implementation. - virtual const void* GetSourceInterface() const; - virtual InterfaceID GetInterfaceId() const; virtual bool OnMessageReceived(const IPC::Message& msg); private: diff --git a/ppapi/proxy/ppp_instance_proxy.cc b/ppapi/proxy/ppp_instance_proxy.cc index 6dabe99..61c97f4 100644 --- a/ppapi/proxy/ppp_instance_proxy.cc +++ b/ppapi/proxy/ppp_instance_proxy.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -100,6 +100,11 @@ static const PPP_Instance instance_interface = { &GetInstanceObject }; +InterfaceProxy* CreateInstanceProxy(Dispatcher* dispatcher, + const void* target_interface) { + return new PPP_Instance_Proxy(dispatcher, target_interface); +} + } // namespace PPP_Instance_Proxy::PPP_Instance_Proxy(Dispatcher* dispatcher, @@ -110,12 +115,16 @@ PPP_Instance_Proxy::PPP_Instance_Proxy(Dispatcher* dispatcher, PPP_Instance_Proxy::~PPP_Instance_Proxy() { } -const void* PPP_Instance_Proxy::GetSourceInterface() const { - return &instance_interface; -} - -InterfaceID PPP_Instance_Proxy::GetInterfaceId() const { - return INTERFACE_ID_PPP_INSTANCE; +// static +const InterfaceProxy::Info* PPP_Instance_Proxy::GetInfo() { + static const Info info = { + &instance_interface, + PPP_INSTANCE_INTERFACE, + INTERFACE_ID_PPP_INSTANCE, + false, + &CreateInstanceProxy, + }; + return &info; } bool PPP_Instance_Proxy::OnMessageReceived(const IPC::Message& msg) { @@ -149,10 +158,12 @@ void PPP_Instance_Proxy::OnMsgDidCreate( if (argn.size() != argv.size()) return; - PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); - if (!dispatcher) - return; - dispatcher->DidCreateInstance(instance); + // Set up the routing associating this new instance with the dispatcher we + // just got the message from. This must be done before calling into the + // plugin so it can in turn call PPAPI functions. + PluginDispatcher* plugin_dispatcher = + static_cast<PluginDispatcher*>(dispatcher()); + plugin_dispatcher->DidCreateInstance(instance); // Make sure the arrays always have at least one element so we can take the // address below. @@ -169,16 +180,16 @@ void PPP_Instance_Proxy::OnMsgDidCreate( *result = ppp_instance_target()->DidCreate(instance, static_cast<uint32_t>(argn.size()), &argn_array[0], &argv_array[0]); - DCHECK(*result); + if (!*result) { + // In the failure to create case, this plugin instance will be torn down + // without further notification, so we also need to undo the routing. + plugin_dispatcher->DidDestroyInstance(instance); + } } void PPP_Instance_Proxy::OnMsgDidDestroy(PP_Instance instance) { ppp_instance_target()->DidDestroy(instance); - PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); - if (!dispatcher) - return; - - dispatcher->DidDestroyInstance(instance); + static_cast<PluginDispatcher*>(dispatcher())->DidDestroyInstance(instance); } void PPP_Instance_Proxy::OnMsgDidChangeView(PP_Instance instance, diff --git a/ppapi/proxy/ppp_instance_proxy.h b/ppapi/proxy/ppp_instance_proxy.h index 8d68b79..318f52f 100644 --- a/ppapi/proxy/ppp_instance_proxy.h +++ b/ppapi/proxy/ppp_instance_proxy.h @@ -28,13 +28,13 @@ class PPP_Instance_Proxy : public InterfaceProxy { PPP_Instance_Proxy(Dispatcher* dispatcher, const void* target_interface); virtual ~PPP_Instance_Proxy(); + static const Info* GetInfo(); + const PPP_Instance* ppp_instance_target() const { return reinterpret_cast<const PPP_Instance*>(target_interface()); } // InterfaceProxy implementation. - virtual const void* GetSourceInterface() const; - virtual InterfaceID GetInterfaceId() const; virtual bool OnMessageReceived(const IPC::Message& msg); private: |