OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ppapi/proxy/host_dispatcher.h" | 5 #include "ppapi/proxy/host_dispatcher.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "ppapi/c/private/ppb_proxy_private.h" | 10 #include "ppapi/c/private/ppb_proxy_private.h" |
11 #include "ppapi/c/dev/ppb_var_deprecated.h" | 11 #include "ppapi/c/dev/ppb_var_deprecated.h" |
12 #include "ppapi/proxy/host_var_serialization_rules.h" | 12 #include "ppapi/proxy/host_var_serialization_rules.h" |
13 #include "ppapi/proxy/ppapi_messages.h" | 13 #include "ppapi/proxy/ppapi_messages.h" |
14 | 14 |
15 namespace pp { | 15 namespace pp { |
16 namespace proxy { | 16 namespace proxy { |
17 | 17 |
18 namespace { | 18 namespace { |
19 | 19 |
20 typedef std::map<PP_Instance, HostDispatcher*> InstanceToDispatcherMap; | 20 typedef std::map<PP_Instance, HostDispatcher*> InstanceToDispatcherMap; |
21 InstanceToDispatcherMap* g_instance_to_dispatcher = NULL; | 21 InstanceToDispatcherMap* g_instance_to_dispatcher = NULL; |
22 | 22 |
| 23 typedef std::map<PP_Module, HostDispatcher*> ModuleToDispatcherMap; |
| 24 ModuleToDispatcherMap* g_module_to_dispatcher = NULL; |
| 25 |
| 26 PP_Bool ReserveInstanceID(PP_Module module, PP_Instance instance) { |
| 27 // Default to returning true (usable) failure. Otherwise, if there's some |
| 28 // kind of communication error or the plugin just crashed, we'll get into an |
| 29 // infinite loop generating new instnace IDs since we think they're all in |
| 30 // use. |
| 31 ModuleToDispatcherMap::const_iterator found = |
| 32 g_module_to_dispatcher->find(module); |
| 33 if (found == g_module_to_dispatcher->end()) { |
| 34 NOTREACHED(); |
| 35 return PP_TRUE; |
| 36 } |
| 37 |
| 38 bool usable = true; |
| 39 if (!found->second->Send(new PpapiMsg_ReserveInstanceId(instance, &usable))) |
| 40 return PP_TRUE; |
| 41 return BoolToPPBool(usable); |
| 42 } |
| 43 |
23 } // namespace | 44 } // namespace |
24 | 45 |
25 HostDispatcher::HostDispatcher(base::ProcessHandle remote_process_handle, | 46 HostDispatcher::HostDispatcher(base::ProcessHandle remote_process_handle, |
26 PP_Module module, | 47 PP_Module module, |
27 GetInterfaceFunc local_get_interface) | 48 GetInterfaceFunc local_get_interface) |
28 : Dispatcher(remote_process_handle, local_get_interface), | 49 : Dispatcher(remote_process_handle, local_get_interface), |
29 pp_module_(module), | 50 pp_module_(module), |
30 ppb_proxy_(NULL) { | 51 ppb_proxy_(NULL) { |
| 52 if (!g_module_to_dispatcher) |
| 53 g_module_to_dispatcher = new ModuleToDispatcherMap; |
| 54 (*g_module_to_dispatcher)[pp_module_] = this; |
| 55 |
31 const PPB_Var_Deprecated* var_interface = | 56 const PPB_Var_Deprecated* var_interface = |
32 static_cast<const PPB_Var_Deprecated*>( | 57 static_cast<const PPB_Var_Deprecated*>( |
33 local_get_interface(PPB_VAR_DEPRECATED_INTERFACE)); | 58 local_get_interface(PPB_VAR_DEPRECATED_INTERFACE)); |
34 SetSerializationRules(new HostVarSerializationRules(var_interface, module)); | 59 SetSerializationRules(new HostVarSerializationRules(var_interface, module)); |
35 | 60 |
36 memset(plugin_interface_support_, 0, | 61 memset(plugin_interface_support_, 0, |
37 sizeof(PluginInterfaceSupport) * INTERFACE_ID_COUNT); | 62 sizeof(PluginInterfaceSupport) * INTERFACE_ID_COUNT); |
| 63 |
| 64 ppb_proxy_ = reinterpret_cast<const PPB_Proxy_Private*>( |
| 65 GetLocalInterface(PPB_PROXY_PRIVATE_INTERFACE)); |
| 66 DCHECK(ppb_proxy_) << "The proxy interface should always be supported."; |
| 67 |
| 68 ppb_proxy_->SetReserveInstanceIDCallback(pp_module_, &ReserveInstanceID); |
38 } | 69 } |
39 | 70 |
40 HostDispatcher::~HostDispatcher() { | 71 HostDispatcher::~HostDispatcher() { |
| 72 g_module_to_dispatcher->erase(pp_module_); |
41 } | 73 } |
42 | 74 |
43 // static | 75 // static |
44 HostDispatcher* HostDispatcher::GetForInstance(PP_Instance instance) { | 76 HostDispatcher* HostDispatcher::GetForInstance(PP_Instance instance) { |
45 if (!g_instance_to_dispatcher) | 77 if (!g_instance_to_dispatcher) |
46 return NULL; | 78 return NULL; |
47 InstanceToDispatcherMap::iterator found = g_instance_to_dispatcher->find( | 79 InstanceToDispatcherMap::iterator found = g_instance_to_dispatcher->find( |
48 instance); | 80 instance); |
49 if (found == g_instance_to_dispatcher->end()) | 81 if (found == g_instance_to_dispatcher->end()) |
50 return NULL; | 82 return NULL; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 proxy = CreatePPBInterfaceProxy(info); | 129 proxy = CreatePPBInterfaceProxy(info); |
98 } | 130 } |
99 | 131 |
100 return proxy->OnMessageReceived(msg); | 132 return proxy->OnMessageReceived(msg); |
101 } | 133 } |
102 | 134 |
103 void HostDispatcher::OnChannelError() { | 135 void HostDispatcher::OnChannelError() { |
104 Dispatcher::OnChannelError(); // Stop using the channel. | 136 Dispatcher::OnChannelError(); // Stop using the channel. |
105 | 137 |
106 // Tell the host about the crash so it can clean up. | 138 // Tell the host about the crash so it can clean up. |
107 GetPPBProxy()->PluginCrashed(pp_module()); | 139 ppb_proxy_->PluginCrashed(pp_module()); |
108 } | 140 } |
109 | 141 |
110 const void* HostDispatcher::GetProxiedInterface(const std::string& interface) { | 142 const void* HostDispatcher::GetProxiedInterface(const std::string& interface) { |
111 // First see if we even have a proxy for this interface. | 143 // First see if we even have a proxy for this interface. |
112 const InterfaceProxy::Info* info = GetPPPInterfaceInfo(interface); | 144 const InterfaceProxy::Info* info = GetPPPInterfaceInfo(interface); |
113 if (!info) | 145 if (!info) |
114 return NULL; | 146 return NULL; |
115 | 147 |
116 if (plugin_interface_support_[static_cast<int>(info->id)] != | 148 if (plugin_interface_support_[static_cast<int>(info->id)] != |
117 INTERFACE_UNQUERIED) { | 149 INTERFACE_UNQUERIED) { |
(...skipping 27 matching lines...) Expand all Loading... |
145 // the plugin the ability to call that trusted interface (since the | 177 // the plugin the ability to call that trusted interface (since the |
146 // checking occurs at proxy-creation time). | 178 // checking occurs at proxy-creation time). |
147 if (info->is_trusted && disallow_trusted_interfaces()) | 179 if (info->is_trusted && disallow_trusted_interfaces()) |
148 return NULL; | 180 return NULL; |
149 | 181 |
150 proxy = CreatePPBInterfaceProxy(info); | 182 proxy = CreatePPBInterfaceProxy(info); |
151 } | 183 } |
152 return proxy; | 184 return proxy; |
153 } | 185 } |
154 | 186 |
155 const PPB_Proxy_Private* HostDispatcher::GetPPBProxy() { | |
156 if (!ppb_proxy_) { | |
157 ppb_proxy_ = reinterpret_cast<const PPB_Proxy_Private*>( | |
158 GetLocalInterface(PPB_PROXY_PRIVATE_INTERFACE)); | |
159 } | |
160 return ppb_proxy_; | |
161 } | |
162 | |
163 InterfaceProxy* HostDispatcher::CreatePPBInterfaceProxy( | 187 InterfaceProxy* HostDispatcher::CreatePPBInterfaceProxy( |
164 const InterfaceProxy::Info* info) { | 188 const InterfaceProxy::Info* info) { |
165 const void* local_interface = GetLocalInterface(info->name); | 189 const void* local_interface = GetLocalInterface(info->name); |
166 if (!local_interface) { | 190 if (!local_interface) { |
167 // This should always succeed since the browser should support the stuff | 191 // This should always succeed since the browser should support the stuff |
168 // the proxy does. If this happens, something is out of sync. | 192 // the proxy does. If this happens, something is out of sync. |
169 NOTREACHED(); | 193 NOTREACHED(); |
170 return NULL; | 194 return NULL; |
171 } | 195 } |
172 | 196 |
173 InterfaceProxy* proxy = info->create_proxy(this, local_interface); | 197 InterfaceProxy* proxy = info->create_proxy(this, local_interface); |
174 target_proxies_[info->id].reset(proxy); | 198 target_proxies_[info->id].reset(proxy); |
175 return proxy; | 199 return proxy; |
176 } | 200 } |
177 | 201 |
178 } // namespace proxy | 202 } // namespace proxy |
179 } // namespace pp | 203 } // namespace pp |
180 | 204 |
OLD | NEW |