diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-08 16:31:46 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-08 16:31:46 +0000 |
commit | 465faa29046328890a224677db522f1aece8cad0 (patch) | |
tree | 5cf23803cc13d27c71c05c4532a5fc434e6d7e4d /ppapi/proxy/host_dispatcher.cc | |
parent | a313e51c562c3d3400d2bd14231f23e9ca699857 (diff) | |
download | chromium_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/proxy/host_dispatcher.cc')
-rw-r--r-- | ppapi/proxy/host_dispatcher.cc | 65 |
1 files changed, 65 insertions, 0 deletions
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 |