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)#ifndef PPAPI_PROXY_HOST_DISPATCHER_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PPAPI_PROXY_HOST_DISPATCHER_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 1334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)#include "base/memory/weak_ptr.h" 1434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)#include "base/observer_list.h" 1558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "base/process/process.h" 165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ipc/message_filter.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_instance.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/dispatcher.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PPB_Proxy_Private; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ppapi { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Preferences; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace proxy { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PPAPI_PROXY_EXPORT HostDispatcher : public Dispatcher { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This interface receives notifications about sync messages being sent by 3134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles) // the dispatcher to the plugin process. Some parts of Chrome may need to 3234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles) // know whether we are sending a synchronous message to the plugin; e.g. to 3334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles) // detect a hung plugin or to avoid re-entering JavaScript. 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that there can be nested sync messages, so the begin/end status 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // actually represents a stack of blocking messages. 3734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles) class SyncMessageStatusObserver { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Notification that a sync message is about to be sent out. 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void BeginBlockOnSyncMessage() = 0; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Notification that a sync message reply was received and the dispatcher 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is no longer blocked on a sync message. 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void EndBlockOnSyncMessage() = 0; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 4734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles) virtual ~SyncMessageStatusObserver() {} 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Constructor for the renderer side. This will take a reference to the 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SyncMessageStatusReceiver. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // You must call InitHostWithChannel after the constructor. 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostDispatcher(PP_Module module, 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_GetInterface_Func local_get_interface, 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PpapiPermissions& permissions); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~HostDispatcher(); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // You must call this function before anything else. Returns true on success. 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The delegate pointer must outlive this class, ownership is not 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // transferred. 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool InitHostWithChannel(Delegate* delegate, 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ProcessId peer_pid, 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const IPC::ChannelHandle& channel_handle, 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_client, 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Preferences& preferences); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The host side maintains a mapping from PP_Instance to Dispatcher so 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that we can send the messages to the right channel. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static HostDispatcher* GetForInstance(PP_Instance instance); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void SetForInstance(PP_Instance instance, 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostDispatcher* dispatcher); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void RemoveForInstance(PP_Instance instance); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the host's notion of our PP_Module. This will be different than 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the plugin's notion of its PP_Module because the plugin process may be 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // used by multiple renderer processes. 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use this value instead of a value from the plugin whenever talking to the 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // host. 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Module pp_module() const { return pp_module_; } 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Dispatcher overrides. 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool IsPlugin() const; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool Send(IPC::Message* msg); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IPC::Listener. 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnChannelError() OVERRIDE; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Proxied version of calling GetInterface on the plugin. This will check 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if the plugin supports the given interface (with caching) and returns the 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pointer to the proxied interface if it is supported. Returns NULL if the 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // given interface isn't supported by the plugin or the proxy. 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* GetProxiedInterface(const std::string& iface_name); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See the value below. Call this when processing a scripting message from 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the plugin that can be reentered. This is set to false at the beginning 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of processing of each message from the plugin. 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_allow_plugin_reentrancy() { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allow_plugin_reentrancy_ = true; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the proxy interface for talking to the implementation. 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PPB_Proxy_Private* ppb_proxy() const { return ppb_proxy_; } 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles) // Register an observer that will be invoked when the dispatcher begins 10834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles) // sending a sync message and finishes sending a sync message. 10934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles) // Returns a Closure that can be used to unregister the observer (the Closure 11034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles) // is bound to a weak pointer, so is safe to call even after the 11134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles) // HostDispatcher is gone.) 11234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles) base::Closure AddSyncMessageStatusObserver(SyncMessageStatusObserver* obs); 11334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles) 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void AddFilter(IPC::Listener* listener); 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Overridden from Dispatcher. 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnInvalidMessageReceived(); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnHostMsgLogWithSource(PP_Instance instance, 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int int_log_level, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& source, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& value); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles) void RemoveSyncMessageStatusObserver(SyncMessageStatusObserver* obs); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Module pp_module_; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Maps interface name to whether that interface is supported. If an interface 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // name is not in the map, that implies that we haven't queried for it yet. 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef base::hash_map<std::string, bool> PluginSupportedMap; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PluginSupportedMap plugin_supported_; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Guaranteed non-NULL. 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PPB_Proxy_Private* ppb_proxy_; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set to true when the plugin is in a state that it can be reentered by a 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // sync message from the host. We allow reentrancy only when we're processing 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a sync message from the renderer that is a scripting command. When the 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // plugin is in this state, it needs to accept reentrancy since scripting may 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ultimately call back into the plugin. 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool allow_plugin_reentrancy_; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles) ObserverList<SyncMessageStatusObserver> sync_status_observer_list_; 14634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles) 147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<IPC::Listener*> filters_; 148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 14934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles) base::WeakPtrFactory<HostDispatcher> weak_ptr_factory_; 15034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(HostDispatcher); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Create this object on the stack to prevent the module (and hence the 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// dispatcher) from being deleted out from under you. This is necessary when 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// calling some scripting functions that may delete the plugin. 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class does nothing if used on the plugin side. 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ScopedModuleReference { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit ScopedModuleReference(Dispatcher* dispatcher); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~ScopedModuleReference(); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostDispatcher* dispatcher_; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ScopedModuleReference); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace proxy 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ppapi 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // PPAPI_PROXY_HOST_DISPATCHER_H_ 174