plugin_dispatcher.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/plugin_dispatcher.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/message_loop.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_message.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_sync_channel.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/trace_event.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_errors.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/ppp_instance.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/flash_resource.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/flash_clipboard_resource.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/gamepad_resource.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/interface_list.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/interface_proxy.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/plugin_message_filter.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/plugin_resource_tracker.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/plugin_var_serialization_rules.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/ppapi_messages.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/ppb_instance_proxy.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/ppp_class_proxy.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/resource_creation_proxy.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/resource_message_params.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/ppapi_globals.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/proxy_lock.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/resource.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) && !defined(OS_NACL) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/eintr_wrapper.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_channel_posix.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ppapi { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace proxy { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef std::map<PP_Instance, PluginDispatcher*> InstanceToDispatcherMap; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InstanceToDispatcherMap* g_instance_to_dispatcher = NULL; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef std::set<PluginDispatcher*> DispatcherSet; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DispatcherSet* g_live_dispatchers = NULL; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InstanceData::InstanceData() 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : flash_fullscreen(PP_FALSE), 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_request_surrounding_text_pending(false), 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) should_do_request_surrounding_text(false) { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InstanceData::~InstanceData() { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Run any pending mouse lock callback to prevent leaks. 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mouse_lock_callback) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mouse_lock_callback->Abort(); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PluginDispatcher::PluginDispatcher(PP_GetInterface_Func get_interface, 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PpapiPermissions& permissions, 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool incognito) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Dispatcher(get_interface, permissions), 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plugin_delegate_(NULL), 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) received_preferences_(false), 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plugin_dispatcher_id_(0), 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) incognito_(incognito) { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetSerializationRules(new PluginVarSerializationRules(AsWeakPtr())); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!g_live_dispatchers) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_live_dispatchers = new DispatcherSet; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_live_dispatchers->insert(this); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PluginDispatcher::~PluginDispatcher() { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (plugin_delegate_) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plugin_delegate_->Unregister(plugin_dispatcher_id_); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_live_dispatchers->erase(this); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (g_live_dispatchers->empty()) { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete g_live_dispatchers; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_live_dispatchers = NULL; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PluginDispatcher* PluginDispatcher::GetForInstance(PP_Instance instance) { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!g_instance_to_dispatcher) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InstanceToDispatcherMap::iterator found = g_instance_to_dispatcher->find( 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (found == g_instance_to_dispatcher->end()) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return found->second; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PluginDispatcher* PluginDispatcher::GetForResource(const Resource* resource) { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetForInstance(resource->pp_instance()); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const void* PluginDispatcher::GetBrowserInterface(const char* interface_name) { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!interface_name) { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(WARNING) << "|interface_name| is null. Did you forget to add " 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "the |interface_name()| template function to the interface's C++ " 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "wrapper?"; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return InterfaceList::GetInstance()->GetInterfaceForPPB(interface_name); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginDispatcher::LogWithSource(PP_Instance instance, 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_LogLevel_Dev level, 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& source, 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& value) { 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!g_live_dispatchers || !g_instance_to_dispatcher) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (instance) { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InstanceToDispatcherMap::iterator found = 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_instance_to_dispatcher->find(instance); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (found != g_instance_to_dispatcher->end()) { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send just to this specific dispatcher. 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found->second->Send(new PpapiHostMsg_LogWithSource( 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance, static_cast<int>(level), source, value)); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Instance 0 or invalid, send to all dispatchers. 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (DispatcherSet::iterator i = g_live_dispatchers->begin(); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != g_live_dispatchers->end(); ++i) { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*i)->Send(new PpapiHostMsg_LogWithSource( 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance, static_cast<int>(level), source, value)); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const void* PluginDispatcher::GetPluginInterface( 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& interface_name) { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InterfaceMap::iterator found = plugin_interfaces_.find(interface_name); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (found == plugin_interfaces_.end()) { 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* ret = local_get_interface()(interface_name.c_str()); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plugin_interfaces_.insert(std::make_pair(interface_name, ret)); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ret; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return found->second; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PluginDispatcher::InitPluginWithChannel( 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PluginDelegate* delegate, 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const IPC::ChannelHandle& channel_handle, 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_client) { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!Dispatcher::InitWithChannel(delegate, channel_handle, is_client)) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plugin_delegate_ = delegate; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plugin_dispatcher_id_ = plugin_delegate_->Register(this); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The message filter will intercept and process certain messages directly 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on the I/O thread. 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel()->AddFilter( 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new PluginMessageFilter(delegate->GetGloballySeenInstanceIDSet())); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PluginDispatcher::IsPlugin() const { 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PluginDispatcher::Send(IPC::Message* msg) { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT2("ppapi proxy", "PluginDispatcher::Send", 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Class", IPC_MESSAGE_ID_CLASS(msg->type()), 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Line", IPC_MESSAGE_ID_LINE(msg->type())); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We always want plugin->renderer messages to arrive in-order. If some sync 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and some async messages are sent in response to a synchronous 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // renderer->plugin call, the sync reply will be processed before the async 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reply, and everything will be confused. 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allowing all async messages to unblock the renderer means more reentrancy 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // there but gives correct ordering. 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't want reply messages to unblock however, as they will potentially 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // end up on the wrong queue - see crbug.com/122443 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!msg->is_reply()) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msg->set_unblock(true); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (msg->is_sync()) { 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Synchronous messages might be re-entrant, so we need to drop the lock. 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyAutoUnlock unlock; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Dispatcher::Send(msg); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Dispatcher::Send(msg); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PluginDispatcher::OnMessageReceived(const IPC::Message& msg) { 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We need to grab the proxy lock to ensure that we don't collide with the 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // plugin making pepper calls on a different thread. 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyAutoLock lock; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT2("ppapi proxy", "PluginDispatcher::OnMessageReceived", 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Class", IPC_MESSAGE_ID_CLASS(msg.type()), 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Line", IPC_MESSAGE_ID_LINE(msg.type())); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (msg.routing_id() == MSG_ROUTING_CONTROL) { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Handle some plugin-specific control messages. 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool handled = true; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(PluginDispatcher, msg) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(PpapiPluginMsg_ResourceReply, OnMsgResourceReply) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(PpapiMsg_SupportsInterface, OnMsgSupportsInterface) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(PpapiMsg_SetPreferences, OnMsgSetPreferences) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_UNHANDLED(handled = false); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_END_MESSAGE_MAP() 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (handled) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Dispatcher::OnMessageReceived(msg); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginDispatcher::OnChannelError() { 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Dispatcher::OnChannelError(); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The renderer has crashed or exited. This channel and all instances 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // associated with it are no longer valid. 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ForceFreeAllInstances(); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(brettw) free resources too! 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete this; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginDispatcher::DidCreateInstance(PP_Instance instance) { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!g_instance_to_dispatcher) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_instance_to_dispatcher = new InstanceToDispatcherMap; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*g_instance_to_dispatcher)[instance] = this; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_map_[instance] = InstanceData(); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginDispatcher::DidDestroyInstance(PP_Instance instance) { 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InstanceDataMap::iterator it = instance_map_.find(instance); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it != instance_map_.end()) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_map_.erase(it); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (g_instance_to_dispatcher) { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InstanceToDispatcherMap::iterator found = g_instance_to_dispatcher->find( 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (found != g_instance_to_dispatcher->end()) { 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(found->second == this); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_instance_to_dispatcher->erase(found); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InstanceData* PluginDispatcher::GetInstanceData(PP_Instance instance) { 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InstanceDataMap::iterator it = instance_map_.find(instance); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (it == instance_map_.end()) ? NULL : &it->second; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)thunk::PPB_Instance_API* PluginDispatcher::GetInstanceAPI() { 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<PPB_Instance_Proxy*>( 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetInterfaceProxy(API_ID_PPB_INSTANCE)); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)thunk::ResourceCreationAPI* PluginDispatcher::GetResourceCreationAPI() { 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<ResourceCreationProxy*>( 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetInterfaceProxy(API_ID_RESOURCE_CREATION)); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginDispatcher::DispatchResourceReply( 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ppapi::proxy::ResourceMessageReplyParams& reply_params, 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const IPC::Message& nested_msg) { 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We need to grab the proxy lock to ensure that we don't collide with the 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // plugin making pepper calls on a different thread. 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyAutoLock lock; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LockedDispatchResourceReply(reply_params, nested_msg); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginDispatcher::ForceFreeAllInstances() { 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!g_instance_to_dispatcher) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Iterating will remove each item from the map, so we need to make a copy 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to avoid things changing out from under is. 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InstanceToDispatcherMap temp_map = *g_instance_to_dispatcher; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (InstanceToDispatcherMap::iterator i = temp_map.begin(); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != temp_map.end(); ++i) { 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i->second == this) { 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Synthesize an "instance destroyed" message, this will notify the 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // plugin and also remove it from our list of tracked plugins. 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PpapiMsg_PPPInstance_DidDestroy msg(API_ID_PPP_INSTANCE, i->first); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnMessageReceived(msg); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginDispatcher::OnMsgResourceReply( 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ppapi::proxy::ResourceMessageReplyParams& reply_params, 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const IPC::Message& nested_msg) { 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LockedDispatchResourceReply(reply_params, nested_msg); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginDispatcher::OnMsgSupportsInterface( 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& interface_name, 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool* result) { 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = !!GetPluginInterface(interface_name); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do fallback for PPP_Instance. This is a hack here and if we have more 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cases like this it should be generalized. The PPP_Instance proxy always 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // proxies the 1.1 interface, and then does fallback to 1.0 inside the 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // plugin process (see PPP_Instance_Proxy). So here we return true for 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // supporting the 1.1 interface if either 1.1 or 1.0 is supported. 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!*result && interface_name == PPP_INSTANCE_INTERFACE) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = !!GetPluginInterface(PPP_INSTANCE_INTERFACE_1_0); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginDispatcher::OnMsgSetPreferences(const Preferences& prefs) { 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The renderer may send us preferences more than once (currently this 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // happens every time a new plugin instance is created). Since we don't have 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a way to signal to the plugin that the preferences have changed, changing 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the default fonts and such in the middle of a running plugin could be 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // confusing to it. As a result, we never allow the preferences to be changed 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // once they're set. The user will have to restart to get new font prefs 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // propogated to plugins. 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!received_preferences_) { 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) received_preferences_ = true; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) preferences_ = prefs; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginDispatcher::LockedDispatchResourceReply( 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ppapi::proxy::ResourceMessageReplyParams& reply_params, 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const IPC::Message& nested_msg) { 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Resource* resource = PpapiGlobals::Get()->GetResourceTracker()->GetResource( 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reply_params.pp_resource()); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!resource) { 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (reply_params.sequence()) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resource->OnReplyReceived(reply_params, nested_msg); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace proxy 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ppapi 351