blob: 08d4dd6d5b4902de944c0c4c7f184cc91c3d39ed [file] [log] [blame]
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef PPAPI_PROXY_HOST_DISPATCHER_H_
#define PPAPI_PROXY_HOST_DISPATCHER_H_
#include <map>
#include <string>
#include <vector>
#include "base/memory/scoped_ptr.h"
#include "base/process.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/proxy/dispatcher.h"
#include "ppapi/shared_impl/function_group_base.h"
struct PPB_Proxy_Private;
struct PPB_Var_Deprecated;
namespace base {
class WaitableEvent;
}
namespace IPC {
class SyncChannel;
}
namespace ppapi {
struct Preferences;
}
namespace pp {
namespace proxy {
class InterfaceProxy;
class VarSerialization;
class HostDispatcher : public Dispatcher {
public:
// Constructor for the renderer side.
//
// You must call InitHostWithChannel after the constructor.
HostDispatcher(base::ProcessHandle host_process_handle,
PP_Module module,
GetInterfaceFunc local_get_interface);
~HostDispatcher();
// You must call this function before anything else. Returns true on success.
// The delegate pointer must outlive this class, ownership is not
// transferred.
virtual bool InitHostWithChannel(Delegate* delegate,
const IPC::ChannelHandle& channel_handle,
bool is_client,
const ppapi::Preferences& preferences);
// The host side maintains a mapping from PP_Instance to Dispatcher so
// that we can send the messages to the right channel.
static HostDispatcher* GetForInstance(PP_Instance instance);
static void SetForInstance(PP_Instance instance,
HostDispatcher* dispatcher);
static void RemoveForInstance(PP_Instance instance);
// Returns the host's notion of our PP_Module. This will be different than
// the plugin's notion of its PP_Module because the plugin process may be
// used by multiple renderer processes.
//
// Use this value instead of a value from the plugin whenever talking to the
// host.
PP_Module pp_module() const { return pp_module_; }
// Dispatcher overrides.
virtual bool IsPlugin() const;
virtual bool Send(IPC::Message* msg);
// IPC::Channel::Listener.
virtual bool OnMessageReceived(const IPC::Message& msg);
virtual void OnChannelError();
// Proxied version of calling GetInterface on the plugin. This will check
// if the plugin supports the given interface (with caching) and returns the
// pointer to the proxied interface if it is supported. Returns NULL if the
// given interface isn't supported by the plugin or the proxy.
const void* GetProxiedInterface(const std::string& interface);
// Returns the proxy object associated with the given interface ID, creating
// it if necessary. This is used in cases where a proxy needs to access code
// in the proxy for another interface. It's assumed that the interface always
// exists, so this is only used for browser proxies.
//
// Will return NULL if an interface isn't supported.
InterfaceProxy* GetOrCreatePPBInterfaceProxy(InterfaceID id);
// See the value below. Call this when processing a scripting message from
// the plugin that can be reentered.
void set_allow_plugin_reentrancy() {
allow_plugin_reentrancy_ = true;
}
// Returns the proxy interface for talking to the implementation.
const PPB_Proxy_Private* ppb_proxy() const { return ppb_proxy_; }
private:
friend class HostDispatcherTest;
// Makes an instance of the given PPB interface proxy, storing it in the
// target_proxies_ array. An proxy for this interface must not exist yet.
InterfaceProxy* CreatePPBInterfaceProxy(const InterfaceProxy::Info* info);
PP_Module pp_module_;
typedef std::map<std::string, bool> PluginIFSupportedMap;
// Maps interface name to whether that interface is supported. If an interface
// name is not in the map, that implies that we haven't queried for it yet.
std::map<std::string, bool> plugin_if_supported_;
// All target proxies currently created. These are ones that receive
// messages. They are created on demand when we receive messages.
scoped_ptr<InterfaceProxy> target_proxies_[INTERFACE_ID_COUNT];
// Function proxies created for "new-style" FunctionGroups.
// TODO(brettw) this is in progress. It should be merged with the target
// proxies so there is one list to consult.
scoped_ptr< ::ppapi::FunctionGroupBase >
function_proxies_[INTERFACE_ID_COUNT];
// Guaranteed non-NULL.
const PPB_Proxy_Private* ppb_proxy_;
// Set to true when the plugin is in a state that it can be reentered by a
// sync message from the host. We allow reentrancy only when we're processing
// a sync message from the renderer that is a scripting command. When the
// plugin is in this state, it needs to accept reentrancy since scripting may
// ultimately call back into the plugin.
bool allow_plugin_reentrancy_;
DISALLOW_COPY_AND_ASSIGN(HostDispatcher);
};
// Create this object on the stack to prevent the module (and hence the
// dispatcher) from being deleted out from under you. This is necessary when
// calling some scripting functions that may delete the plugin.
//
// This may only be called in the host. The parameter is a plain Dispatcher
// since that's what most callers have.
class ScopedModuleReference {
public:
ScopedModuleReference(Dispatcher* dispatcher);
~ScopedModuleReference();
private:
HostDispatcher* dispatcher_;
DISALLOW_COPY_AND_ASSIGN(ScopedModuleReference);
};
} // namespace proxy
} // namespace pp
#endif // PPAPI_PROXY_HOST_DISPATCHER_H_