Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(306)

Unified Diff: ppapi/proxy/plugin_dispatcher.cc

Issue 6286070: Remove all uses of the global Dispatcher Get function. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ppapi/proxy/plugin_dispatcher.h ('k') | ppapi/proxy/plugin_dispatcher_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ppapi/proxy/plugin_dispatcher.cc
===================================================================
--- ppapi/proxy/plugin_dispatcher.cc (revision 74021)
+++ ppapi/proxy/plugin_dispatcher.cc (working copy)
@@ -21,11 +21,15 @@
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 @@
// 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 @@
}
// 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::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 @@
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 @@
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
« no previous file with comments | « ppapi/proxy/plugin_dispatcher.h ('k') | ppapi/proxy/plugin_dispatcher_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698