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/host_dispatcher.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/trace_event.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/private/ppb_proxy_private.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/ppb_var.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/host_var_serialization_rules.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/interface_list.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/ppapi_messages.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/resource_creation_proxy.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/ppapi_globals.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ppapi {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace proxy {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef std::map<PP_Instance, HostDispatcher*> InstanceToDispatcherMap;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InstanceToDispatcherMap* g_instance_to_dispatcher = NULL;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef std::map<PP_Module, HostDispatcher*> ModuleToDispatcherMap;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ModuleToDispatcherMap* g_module_to_dispatcher = NULL;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Bool ReserveInstanceID(PP_Module module, PP_Instance instance) {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Default to returning true (usable) failure. Otherwise, if there's some
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // kind of communication error or the plugin just crashed, we'll get into an
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // infinite loop generating new instnace IDs since we think they're all in
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // use.
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ModuleToDispatcherMap::const_iterator found =
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      g_module_to_dispatcher->find(module);
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (found == g_module_to_dispatcher->end()) {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PP_TRUE;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool usable = true;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!found->second->Send(new PpapiMsg_ReserveInstanceId(instance, &usable)))
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PP_TRUE;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_FromBool(usable);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Saves the state of the given bool and puts it back when it goes out of
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// scope.
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BoolRestorer {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BoolRestorer(bool* var) : var_(var), old_value_(*var) {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~BoolRestorer() {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *var_ = old_value_;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool* var_;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool old_value_;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HostDispatcher::HostDispatcher(PP_Module module,
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               PP_GetInterface_Func local_get_interface,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               SyncMessageStatusReceiver* sync_status,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const PpapiPermissions& permissions)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : Dispatcher(local_get_interface, permissions),
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sync_status_(sync_status),
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pp_module_(module),
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ppb_proxy_(NULL),
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      allow_plugin_reentrancy_(false) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!g_module_to_dispatcher)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_module_to_dispatcher = new ModuleToDispatcherMap;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (*g_module_to_dispatcher)[pp_module_] = this;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetSerializationRules(new HostVarSerializationRules);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ppb_proxy_ = reinterpret_cast<const PPB_Proxy_Private*>(
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      local_get_interface(PPB_PROXY_PRIVATE_INTERFACE));
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(ppb_proxy_) << "The proxy interface should always be supported.";
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ppb_proxy_->SetReserveInstanceIDCallback(pp_module_, &ReserveInstanceID);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HostDispatcher::~HostDispatcher() {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_module_to_dispatcher->erase(pp_module_);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HostDispatcher::InitHostWithChannel(
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Delegate* delegate,
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::ProcessId peer_pid,
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const IPC::ChannelHandle& channel_handle,
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool is_client,
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ppapi::Preferences& preferences) {
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!Dispatcher::InitWithChannel(delegate, peer_pid, channel_handle,
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   is_client))
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddIOThreadMessageFilter(sync_status_.get());
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(new PpapiMsg_SetPreferences(preferences));
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HostDispatcher* HostDispatcher::GetForInstance(PP_Instance instance) {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!g_instance_to_dispatcher)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InstanceToDispatcherMap::iterator found = g_instance_to_dispatcher->find(
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (found == g_instance_to_dispatcher->end())
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return found->second;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HostDispatcher::SetForInstance(PP_Instance instance,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    HostDispatcher* dispatcher) {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!g_instance_to_dispatcher)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_instance_to_dispatcher = new InstanceToDispatcherMap;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (*g_instance_to_dispatcher)[instance] = dispatcher;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HostDispatcher::RemoveForInstance(PP_Instance instance) {
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!g_instance_to_dispatcher)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InstanceToDispatcherMap::iterator found = g_instance_to_dispatcher->find(
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (found != g_instance_to_dispatcher->end())
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_instance_to_dispatcher->erase(found);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HostDispatcher::IsPlugin() const {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HostDispatcher::Send(IPC::Message* msg) {
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT2("ppapi proxy", "HostDispatcher::Send",
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               "Class", IPC_MESSAGE_ID_CLASS(msg->type()),
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               "Line", IPC_MESSAGE_ID_LINE(msg->type()));
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Normal sync messages are set to unblock, which would normally cause the
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // plugin to be reentered to process them. We only want to do this when we
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // know the plugin is in a state to accept reentrancy. Since the plugin side
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // never clears this flag on messages it sends, we can't get deadlock, but we
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // may still get reentrancy in the host as a result.
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!allow_plugin_reentrancy_)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    msg->set_unblock(false);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (msg->is_sync()) {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Don't allow sending sync messages during module shutdown. Seee the "else"
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // block below for why.
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(!PP_ToBool(ppb_proxy()->IsInModuleDestructor(pp_module())));
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Prevent the dispatcher from going away during sync calls. Scenarios
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // where this could happen include a Send for a sync message which while
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // waiting for the reply, dispatches an incoming ExecuteScript call which
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // destroys the plugin module and in turn the dispatcher.
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScopedModuleReference scoped_ref(this);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_status_->BeginBlockOnSyncMessage();
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool result = Dispatcher::Send(msg);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_status_->EndBlockOnSyncMessage();
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We don't want to have a scoped ref for async message cases since since
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // async messages are sent during module desruction. In this case, the
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // module will have a 0 refcount and addrefing and releasing it will
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // reenter the destructor and it will crash.
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return Dispatcher::Send(msg);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HostDispatcher::OnMessageReceived(const IPC::Message& msg) {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Prevent the dispatcher from going away during a message handler. This must
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be at the outermost scope so it's released last.
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedModuleReference death_grip(this);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT2("ppapi proxy", "HostDispatcher::OnMessageReceived",
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               "Class", IPC_MESSAGE_ID_CLASS(msg.type()),
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               "Line", IPC_MESSAGE_ID_LINE(msg.type()));
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We only want to allow reentrancy when the most recent message from the
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // plugin was a scripting message. We save the old state of the flag on the
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // stack in case we're (we are the host) being reentered ourselves. The flag
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is set to false here for all messages, and then the scripting API will
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // explicitly set it to true during processing of those messages that can be
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // reentered.
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BoolRestorer restorer(&allow_plugin_reentrancy_);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  allow_plugin_reentrancy_ = false;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < filters_.size(); i++) {
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (filters_[i]->OnMessageReceived(msg))
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool handled = true;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(HostDispatcher, msg)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(PpapiHostMsg_LogWithSource, OnHostMsgLogWithSource)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_END_MESSAGE_MAP()
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (handled)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Dispatcher::OnMessageReceived(msg);
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: |this| may be deleted once the death_grip goes out of scope!
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HostDispatcher::OnChannelError() {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Dispatcher::OnChannelError();  // Stop using the channel.
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Tell the host about the crash so it can clean up and display notification.
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ppb_proxy_->PluginCrashed(pp_module());
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const void* HostDispatcher::GetProxiedInterface(const std::string& iface_name) {
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const void* proxied_interface =
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      InterfaceList::GetInstance()->GetInterfaceForPPP(iface_name);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!proxied_interface)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;  // Don't have a proxy for this interface, don't query further.
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PluginSupportedMap::iterator iter(plugin_supported_.find(iface_name));
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (iter == plugin_supported_.end()) {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Need to query. Cache the result so we only do this once.
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool supported = false;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool previous_reentrancy_value = allow_plugin_reentrancy_;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    allow_plugin_reentrancy_ = true;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new PpapiMsg_SupportsInterface(iface_name, &supported));
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    allow_plugin_reentrancy_ = previous_reentrancy_value;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::pair<PluginSupportedMap::iterator, bool> iter_success_pair;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    iter_success_pair = plugin_supported_.insert(
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PluginSupportedMap::value_type(iface_name, supported));
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    iter = iter_success_pair.first;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (iter->second)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return proxied_interface;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HostDispatcher::OnInvalidMessageReceived() {
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(brettw) bug 95345 kill the plugin when an invalid message is
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // received.
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HostDispatcher::OnHostMsgLogWithSource(PP_Instance instance,
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            int int_log_level,
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            const std::string& source,
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            const std::string& value) {
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PP_LogLevel level = static_cast<PP_LogLevel>(int_log_level);
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (instance) {
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PpapiGlobals::Get()->LogWithSource(instance, level, source, value);
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PpapiGlobals::Get()->BroadcastLogWithSource(pp_module_, level,
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                source, value);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ScopedModuleReference -------------------------------------------------------
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedModuleReference::ScopedModuleReference(Dispatcher* dispatcher)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : dispatcher_(NULL) {
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!dispatcher->IsPlugin()) {
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dispatcher_ = static_cast<HostDispatcher*>(dispatcher);
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dispatcher_->ppb_proxy()->AddRefModule(dispatcher_->pp_module());
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedModuleReference::~ScopedModuleReference() {
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (dispatcher_)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dispatcher_->ppb_proxy()->ReleaseModule(dispatcher_->pp_module());
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace proxy
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ppapi
278