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

Side by Side Diff: ppapi/proxy/plugin_dispatcher.cc

Issue 7844018: Revert 100748 - This patch tries to remove most of the manual registration for Pepper interfaces,... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 3 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ppapi/proxy/plugin_dispatcher.h ('k') | ppapi/proxy/plugin_dispatcher_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/plugin_dispatcher.h" 5 #include "ppapi/proxy/plugin_dispatcher.h"
6 6
7 #include <map> 7 #include <map>
8 8
9 #include "base/compiler_specific.h" 9 #include "base/compiler_specific.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/message_loop.h" 11 #include "base/message_loop.h"
12 #include "ipc/ipc_message.h" 12 #include "ipc/ipc_message.h"
13 #include "ipc/ipc_sync_channel.h" 13 #include "ipc/ipc_sync_channel.h"
14 #include "base/debug/trace_event.h" 14 #include "base/debug/trace_event.h"
15 #include "ppapi/c/pp_errors.h" 15 #include "ppapi/c/pp_errors.h"
16 #include "ppapi/proxy/interface_list.h"
17 #include "ppapi/proxy/interface_proxy.h" 16 #include "ppapi/proxy/interface_proxy.h"
18 #include "ppapi/proxy/plugin_message_filter.h" 17 #include "ppapi/proxy/plugin_message_filter.h"
19 #include "ppapi/proxy/plugin_resource_tracker.h" 18 #include "ppapi/proxy/plugin_resource_tracker.h"
20 #include "ppapi/proxy/plugin_var_serialization_rules.h" 19 #include "ppapi/proxy/plugin_var_serialization_rules.h"
21 #include "ppapi/proxy/ppapi_messages.h" 20 #include "ppapi/proxy/ppapi_messages.h"
22 #include "ppapi/proxy/ppb_char_set_proxy.h" 21 #include "ppapi/proxy/ppb_char_set_proxy.h"
23 #include "ppapi/proxy/ppb_cursor_control_proxy.h" 22 #include "ppapi/proxy/ppb_cursor_control_proxy.h"
24 #include "ppapi/proxy/ppb_font_proxy.h" 23 #include "ppapi/proxy/ppb_font_proxy.h"
25 #include "ppapi/proxy/ppb_instance_proxy.h" 24 #include "ppapi/proxy/ppb_instance_proxy.h"
26 #include "ppapi/proxy/ppp_class_proxy.h" 25 #include "ppapi/proxy/ppp_class_proxy.h"
(...skipping 16 matching lines...) Expand all
43 42
44 } // namespace 43 } // namespace
45 44
46 PluginDispatcher::PluginDispatcher(base::ProcessHandle remote_process_handle, 45 PluginDispatcher::PluginDispatcher(base::ProcessHandle remote_process_handle,
47 GetInterfaceFunc get_interface) 46 GetInterfaceFunc get_interface)
48 : Dispatcher(remote_process_handle, get_interface), 47 : Dispatcher(remote_process_handle, get_interface),
49 plugin_delegate_(NULL), 48 plugin_delegate_(NULL),
50 received_preferences_(false), 49 received_preferences_(false),
51 plugin_dispatcher_id_(0) { 50 plugin_dispatcher_id_(0) {
52 SetSerializationRules(new PluginVarSerializationRules); 51 SetSerializationRules(new PluginVarSerializationRules);
52
53 // As a plugin, we always support the PPP_Class interface. There's no
54 // GetInterface call or name for it, so we insert it into our table now.
55 target_proxies_[INTERFACE_ID_PPP_CLASS].reset(new PPP_Class_Proxy(this));
56
53 TrackerBase::Init(&PluginResourceTracker::GetTrackerBaseInstance); 57 TrackerBase::Init(&PluginResourceTracker::GetTrackerBaseInstance);
54 } 58 }
55 59
56 PluginDispatcher::~PluginDispatcher() { 60 PluginDispatcher::~PluginDispatcher() {
57 if (plugin_delegate_) 61 if (plugin_delegate_)
58 plugin_delegate_->Unregister(plugin_dispatcher_id_); 62 plugin_delegate_->Unregister(plugin_dispatcher_id_);
59 } 63 }
60 64
61 // static 65 // static
62 PluginDispatcher* PluginDispatcher::GetForInstance(PP_Instance instance) { 66 PluginDispatcher* PluginDispatcher::GetForInstance(PP_Instance instance) {
63 if (!g_instance_to_dispatcher) 67 if (!g_instance_to_dispatcher)
64 return NULL; 68 return NULL;
65 InstanceToDispatcherMap::iterator found = g_instance_to_dispatcher->find( 69 InstanceToDispatcherMap::iterator found = g_instance_to_dispatcher->find(
66 instance); 70 instance);
67 if (found == g_instance_to_dispatcher->end()) 71 if (found == g_instance_to_dispatcher->end())
68 return NULL; 72 return NULL;
69 return found->second; 73 return found->second;
70 } 74 }
71 75
72 // static 76 // static
73 PluginDispatcher* PluginDispatcher::GetForResource(const Resource* resource) { 77 PluginDispatcher* PluginDispatcher::GetForResource(const Resource* resource) {
74 return GetForInstance(resource->pp_instance()); 78 return GetForInstance(resource->pp_instance());
75 } 79 }
76 80
77 // static 81 // static
78 const void* PluginDispatcher::GetBrowserInterface(const char* interface) { 82 const void* PluginDispatcher::GetInterfaceFromDispatcher(
79 return InterfaceList::GetInstance()->GetInterfaceForPPB(interface); 83 const char* dispatcher_interface) {
80 } 84 // All interfaces the plugin requests of the browser are "PPB".
81 85 const InterfaceProxy::Info* info = GetPPBInterfaceInfo(dispatcher_interface);
82 const void* PluginDispatcher::GetPluginInterface( 86 if (!info)
83 const std::string& interface_name) { 87 return NULL;
84 InterfaceMap::iterator found = plugin_interfaces_.find(interface_name); 88 return info->interface_ptr;
85 if (found == plugin_interfaces_.end()) {
86 const void* ret = local_get_interface()(interface_name.c_str());
87 plugin_interfaces_.insert(std::make_pair(interface_name, ret));
88 return ret;
89 }
90 return found->second;
91 } 89 }
92 90
93 bool PluginDispatcher::InitPluginWithChannel( 91 bool PluginDispatcher::InitPluginWithChannel(
94 PluginDelegate* delegate, 92 PluginDelegate* delegate,
95 const IPC::ChannelHandle& channel_handle, 93 const IPC::ChannelHandle& channel_handle,
96 bool is_client) { 94 bool is_client) {
97 if (!Dispatcher::InitWithChannel(delegate, channel_handle, is_client)) 95 if (!Dispatcher::InitWithChannel(delegate, channel_handle, is_client))
98 return false; 96 return false;
99 plugin_delegate_ = delegate; 97 plugin_delegate_ = delegate;
100 plugin_dispatcher_id_ = plugin_delegate_->Register(this); 98 plugin_dispatcher_id_ = plugin_delegate_->Register(this);
(...skipping 21 matching lines...) Expand all
122 // Allowing all async messages to unblock the renderer means more reentrancy 120 // Allowing all async messages to unblock the renderer means more reentrancy
123 // there but gives correct ordering. 121 // there but gives correct ordering.
124 msg->set_unblock(true); 122 msg->set_unblock(true);
125 return Dispatcher::Send(msg); 123 return Dispatcher::Send(msg);
126 } 124 }
127 125
128 bool PluginDispatcher::OnMessageReceived(const IPC::Message& msg) { 126 bool PluginDispatcher::OnMessageReceived(const IPC::Message& msg) {
129 TRACE_EVENT2("ppapi proxy", "PluginDispatcher::OnMessageReceived", 127 TRACE_EVENT2("ppapi proxy", "PluginDispatcher::OnMessageReceived",
130 "Class", IPC_MESSAGE_ID_CLASS(msg.type()), 128 "Class", IPC_MESSAGE_ID_CLASS(msg.type()),
131 "Line", IPC_MESSAGE_ID_LINE(msg.type())); 129 "Line", IPC_MESSAGE_ID_LINE(msg.type()));
130 // Handle common control messages.
131 if (Dispatcher::OnMessageReceived(msg))
132 return true;
133
132 if (msg.routing_id() == MSG_ROUTING_CONTROL) { 134 if (msg.routing_id() == MSG_ROUTING_CONTROL) {
133 // Handle some plugin-specific control messages. 135 // Handle some plugin-specific control messages.
134 bool handled = true; 136 bool handled = true;
135 IPC_BEGIN_MESSAGE_MAP(PluginDispatcher, msg) 137 IPC_BEGIN_MESSAGE_MAP(PluginDispatcher, msg)
136 IPC_MESSAGE_HANDLER(PpapiMsg_SupportsInterface, OnMsgSupportsInterface) 138 IPC_MESSAGE_HANDLER(PpapiMsg_SupportsInterface, OnMsgSupportsInterface)
137 IPC_MESSAGE_HANDLER(PpapiMsg_SetPreferences, OnMsgSetPreferences) 139 IPC_MESSAGE_HANDLER(PpapiMsg_SetPreferences, OnMsgSetPreferences)
138 IPC_MESSAGE_UNHANDLED(handled = false);
139 IPC_END_MESSAGE_MAP() 140 IPC_END_MESSAGE_MAP()
140 if (handled) 141 return handled;
142 }
143
144 if (msg.routing_id() <= 0 || msg.routing_id() >= INTERFACE_ID_COUNT) {
145 // Host is sending us garbage. Since it's supposed to be trusted, this
146 // isn't supposed to happen. Crash here in all builds in case the renderer
147 // is compromised.
148 CHECK(false);
149 return true;
150 }
151
152 // There are two cases:
153 //
154 // * The first case is that the host is calling a PPP interface. It will
155 // always do a check for the interface before sending messages, and this
156 // will create the necessary interface proxy at that time. So when we
157 // actually receive a message, we know such a proxy will exist.
158 //
159 // * The second case is that the host is sending a response to the plugin
160 // side of a PPB interface (some, like the URL loader, have complex
161 // response messages). Since the host is trusted and not supposed to be
162 // doing silly things, we can just create a PPB proxy project on demand the
163 // first time it's needed.
164
165 InterfaceProxy* proxy = target_proxies_[msg.routing_id()].get();
166 if (!proxy) {
167 // Handle the first time the host calls a PPB reply interface by
168 // autocreating it.
169 const InterfaceProxy::Info* info = GetPPBInterfaceInfo(
170 static_cast<InterfaceID>(msg.routing_id()));
171 if (!info) {
172 NOTREACHED();
141 return true; 173 return true;
174 }
175 proxy = info->create_proxy(this, NULL);
176 target_proxies_[info->id].reset(proxy);
142 } 177 }
143 return Dispatcher::OnMessageReceived(msg); 178
179 return proxy->OnMessageReceived(msg);
144 } 180 }
145 181
146 void PluginDispatcher::OnChannelError() { 182 void PluginDispatcher::OnChannelError() {
147 Dispatcher::OnChannelError(); 183 Dispatcher::OnChannelError();
148 184
149 // The renderer has crashed or exited. This channel and all instances 185 // The renderer has crashed or exited. This channel and all instances
150 // associated with it are no longer valid. 186 // associated with it are no longer valid.
151 ForceFreeAllInstances(); 187 ForceFreeAllInstances();
152 // TODO(brettw) free resources too! 188 // TODO(brettw) free resources too!
153 delete this; 189 delete this;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 227
192 bool PluginDispatcher::SendToBrowser(IPC::Message* msg) { 228 bool PluginDispatcher::SendToBrowser(IPC::Message* msg) {
193 return plugin_delegate_->SendToBrowser(msg); 229 return plugin_delegate_->SendToBrowser(msg);
194 } 230 }
195 231
196 WebKitForwarding* PluginDispatcher::GetWebKitForwarding() { 232 WebKitForwarding* PluginDispatcher::GetWebKitForwarding() {
197 return plugin_delegate_->GetWebKitForwarding(); 233 return plugin_delegate_->GetWebKitForwarding();
198 } 234 }
199 235
200 FunctionGroupBase* PluginDispatcher::GetFunctionAPI(InterfaceID id) { 236 FunctionGroupBase* PluginDispatcher::GetFunctionAPI(InterfaceID id) {
201 return GetInterfaceProxy(id); 237 scoped_ptr<FunctionGroupBase >& proxy = function_proxies_[id];
238
239 if (proxy.get())
240 return proxy.get();
241
242 if (id == INTERFACE_ID_PPB_CHAR_SET)
243 proxy.reset(new PPB_CharSet_Proxy(this, NULL));
244 else if(id == INTERFACE_ID_PPB_CURSORCONTROL)
245 proxy.reset(new PPB_CursorControl_Proxy(this, NULL));
246 else if (id == INTERFACE_ID_PPB_FONT)
247 proxy.reset(new PPB_Font_Proxy(this, NULL));
248 else if (id == INTERFACE_ID_PPB_INSTANCE)
249 proxy.reset(new PPB_Instance_Proxy(this, NULL));
250 else if (id == INTERFACE_ID_RESOURCE_CREATION)
251 proxy.reset(new ResourceCreationProxy(this));
252
253 return proxy.get();
202 } 254 }
203 255
204 void PluginDispatcher::ForceFreeAllInstances() { 256 void PluginDispatcher::ForceFreeAllInstances() {
205 if (!g_instance_to_dispatcher) 257 if (!g_instance_to_dispatcher)
206 return; 258 return;
207 259
208 // Iterating will remove each item from the map, so we need to make a copy 260 // Iterating will remove each item from the map, so we need to make a copy
209 // to avoid things changing out from under is. 261 // to avoid things changing out from under is.
210 InstanceToDispatcherMap temp_map = *g_instance_to_dispatcher; 262 InstanceToDispatcherMap temp_map = *g_instance_to_dispatcher;
211 for (InstanceToDispatcherMap::iterator i = temp_map.begin(); 263 for (InstanceToDispatcherMap::iterator i = temp_map.begin();
212 i != temp_map.end(); ++i) { 264 i != temp_map.end(); ++i) {
213 if (i->second == this) { 265 if (i->second == this) {
214 // Synthesize an "instance destroyed" message, this will notify the 266 // Synthesize an "instance destroyed" message, this will notify the
215 // plugin and also remove it from our list of tracked plugins. 267 // plugin and also remove it from our list of tracked plugins.
216 PpapiMsg_PPPInstance_DidDestroy msg(INTERFACE_ID_PPP_INSTANCE, i->first); 268 PpapiMsg_PPPInstance_DidDestroy msg(INTERFACE_ID_PPP_INSTANCE, i->first);
217 OnMessageReceived(msg); 269 OnMessageReceived(msg);
218 } 270 }
219 } 271 }
220 } 272 }
221 273
222 void PluginDispatcher::OnMsgSupportsInterface( 274 void PluginDispatcher::OnMsgSupportsInterface(
223 const std::string& interface_name, 275 const std::string& interface_name,
224 bool* result) { 276 bool* result) {
225 *result = !!GetPluginInterface(interface_name); 277 *result = false;
278
279 // Setup a proxy for receiving the messages from this interface.
280 const InterfaceProxy::Info* info = GetPPPInterfaceInfo(interface_name);
281 if (!info)
282 return; // Interface not supported by proxy.
283
284 // Check for a cached result.
285 if (target_proxies_[info->id].get()) {
286 *result = true;
287 return;
288 }
289
290 // Query the plugin & cache the result.
291 const void* interface_functions = GetLocalInterface(interface_name.c_str());
292 if (!interface_functions)
293 return;
294 target_proxies_[info->id].reset(
295 info->create_proxy(this, interface_functions));
296 *result = true;
226 } 297 }
227 298
228 void PluginDispatcher::OnMsgSetPreferences(const Preferences& prefs) { 299 void PluginDispatcher::OnMsgSetPreferences(const Preferences& prefs) {
229 // The renderer may send us preferences more than once (currently this 300 // The renderer may send us preferences more than once (currently this
230 // happens every time a new plugin instance is created). Since we don't have 301 // happens every time a new plugin instance is created). Since we don't have
231 // a way to signal to the plugin that the preferences have changed, changing 302 // a way to signal to the plugin that the preferences have changed, changing
232 // the default fonts and such in the middle of a running plugin could be 303 // the default fonts and such in the middle of a running plugin could be
233 // confusing to it. As a result, we never allow the preferences to be changed 304 // confusing to it. As a result, we never allow the preferences to be changed
234 // once they're set. The user will have to restart to get new font prefs 305 // once they're set. The user will have to restart to get new font prefs
235 // propogated to plugins. 306 // propogated to plugins.
236 if (!received_preferences_) { 307 if (!received_preferences_) {
237 received_preferences_ = true; 308 received_preferences_ = true;
238 preferences_ = prefs; 309 preferences_ = prefs;
239 } 310 }
240 } 311 }
241 312
242 } // namespace proxy 313 } // namespace proxy
243 } // namespace ppapi 314 } // namespace ppapi
OLDNEW
« 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