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