summaryrefslogtreecommitdiffstats
path: root/ppapi
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-08 16:31:46 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-08 16:31:46 +0000
commit465faa29046328890a224677db522f1aece8cad0 (patch)
tree5cf23803cc13d27c71c05c4532a5fc434e6d7e4d /ppapi
parenta313e51c562c3d3400d2bd14231f23e9ca699857 (diff)
downloadchromium_src-465faa29046328890a224677db522f1aece8cad0.zip
chromium_src-465faa29046328890a224677db522f1aece8cad0.tar.gz
chromium_src-465faa29046328890a224677db522f1aece8cad0.tar.bz2
Rent syncemove all uses of the global Dispatcher Get function.
This reqired reworking how plugin->host GetInterface works. Previously, interface requests were symmetric where each side would first do a SupportsInterface to see if the remote side supports the interface, then create the proxy. Since the plugin may talk to multiple renderers, we don't know where to send these requests. The solution is to make the assumption that the renderer always supports all PPB interfaces (which is possible since the proxy is compiled with the executable). This also adds some better lookup for interfaces to avoid having multiple lists of interfaces. We now have a list of interfaces and factory functions in dispatcher.cc. Add some additional testing infrastructure for the dispatchers with simple tests. Review URL: http://codereview.chromium.org/6286070 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@74121 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi')
-rw-r--r--ppapi/c/dev/ppb_opengles_dev.h2
-rw-r--r--ppapi/ppapi_tests.gypi2
-rw-r--r--ppapi/proxy/dispatcher.cc291
-rw-r--r--ppapi/proxy/dispatcher.h70
-rw-r--r--ppapi/proxy/host_dispatcher.cc65
-rw-r--r--ppapi/proxy/host_dispatcher.h30
-rw-r--r--ppapi/proxy/host_dispatcher_unittest.cc40
-rw-r--r--ppapi/proxy/interface_id.h2
-rw-r--r--ppapi/proxy/interface_proxy.h58
-rw-r--r--ppapi/proxy/plugin_dispatcher.cc120
-rw-r--r--ppapi/proxy/plugin_dispatcher.h27
-rw-r--r--ppapi/proxy/plugin_dispatcher_unittest.cc88
-rw-r--r--ppapi/proxy/plugin_resource_tracker_unittest.cc3
-rw-r--r--ppapi/proxy/plugin_var_serialization_rules.cc18
-rw-r--r--ppapi/proxy/plugin_var_tracker.cc42
-rw-r--r--ppapi/proxy/plugin_var_tracker.h29
-rw-r--r--ppapi/proxy/plugin_var_tracker_unittest.cc31
-rw-r--r--ppapi/proxy/ppapi_messages_internal.h5
-rw-r--r--ppapi/proxy/ppapi_proxy_test.cc96
-rw-r--r--ppapi/proxy/ppapi_proxy_test.h82
-rw-r--r--ppapi/proxy/ppb_audio_config_proxy.cc21
-rw-r--r--ppapi/proxy/ppb_audio_config_proxy.h4
-rw-r--r--ppapi/proxy/ppb_audio_proxy.cc27
-rw-r--r--ppapi/proxy/ppb_audio_proxy.h4
-rw-r--r--ppapi/proxy/ppb_buffer_proxy.cc25
-rw-r--r--ppapi/proxy/ppb_buffer_proxy.h4
-rw-r--r--ppapi/proxy/ppb_char_set_proxy.cc25
-rw-r--r--ppapi/proxy/ppb_char_set_proxy.h4
-rw-r--r--ppapi/proxy/ppb_context_3d_proxy.cc27
-rw-r--r--ppapi/proxy/ppb_context_3d_proxy.h4
-rw-r--r--ppapi/proxy/ppb_core_proxy.cc23
-rw-r--r--ppapi/proxy/ppb_core_proxy.h4
-rw-r--r--ppapi/proxy/ppb_cursor_control_proxy.cc21
-rw-r--r--ppapi/proxy/ppb_cursor_control_proxy.h4
-rw-r--r--ppapi/proxy/ppb_flash_proxy.cc23
-rw-r--r--ppapi/proxy/ppb_flash_proxy.h4
-rw-r--r--ppapi/proxy/ppb_font_proxy.cc23
-rw-r--r--ppapi/proxy/ppb_font_proxy.h4
-rw-r--r--ppapi/proxy/ppb_fullscreen_proxy.cc23
-rw-r--r--ppapi/proxy/ppb_fullscreen_proxy.h4
-rw-r--r--ppapi/proxy/ppb_gles_chromium_texture_mapping_proxy.cc24
-rw-r--r--ppapi/proxy/ppb_gles_chromium_texture_mapping_proxy.h4
-rw-r--r--ppapi/proxy/ppb_graphics_2d_proxy.cc23
-rw-r--r--ppapi/proxy/ppb_graphics_2d_proxy.h4
-rw-r--r--ppapi/proxy/ppb_image_data_proxy.cc23
-rw-r--r--ppapi/proxy/ppb_image_data_proxy.h4
-rw-r--r--ppapi/proxy/ppb_instance_proxy.cc21
-rw-r--r--ppapi/proxy/ppb_instance_proxy.h4
-rw-r--r--ppapi/proxy/ppb_opengles2_proxy.cc24
-rw-r--r--ppapi/proxy/ppb_opengles2_proxy.h4
-rw-r--r--ppapi/proxy/ppb_pdf_proxy.cc23
-rw-r--r--ppapi/proxy/ppb_pdf_proxy.h4
-rw-r--r--ppapi/proxy/ppb_surface_3d_proxy.cc23
-rw-r--r--ppapi/proxy/ppb_surface_3d_proxy.h4
-rw-r--r--ppapi/proxy/ppb_testing_proxy.cc21
-rw-r--r--ppapi/proxy/ppb_testing_proxy.h4
-rw-r--r--ppapi/proxy/ppb_url_loader_proxy.cc46
-rw-r--r--ppapi/proxy/ppb_url_loader_proxy.h8
-rw-r--r--ppapi/proxy/ppb_url_request_info_proxy.cc23
-rw-r--r--ppapi/proxy/ppb_url_request_info_proxy.h4
-rw-r--r--ppapi/proxy/ppb_url_response_info_proxy.cc27
-rw-r--r--ppapi/proxy/ppb_url_response_info_proxy.h4
-rw-r--r--ppapi/proxy/ppb_var_deprecated_proxy.cc106
-rw-r--r--ppapi/proxy/ppb_var_deprecated_proxy.h4
-rw-r--r--ppapi/proxy/ppp_class_proxy.cc8
-rw-r--r--ppapi/proxy/ppp_class_proxy.h2
-rw-r--r--ppapi/proxy/ppp_instance_proxy.cc45
-rw-r--r--ppapi/proxy/ppp_instance_proxy.h4
68 files changed, 1245 insertions, 629 deletions
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: