// Copyright (c) 2012 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.

#include "ppapi/proxy/plugin_dispatcher.h"

#include <map>

#include "base/compiler_specific.h"
#include "base/debug/trace_event.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_sync_channel.h"
#include "ipc/ipc_sync_message_filter.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/ppp_instance.h"
#include "ppapi/proxy/flash_clipboard_resource.h"
#include "ppapi/proxy/flash_file_resource.h"
#include "ppapi/proxy/flash_resource.h"
#include "ppapi/proxy/gamepad_resource.h"
#include "ppapi/proxy/interface_list.h"
#include "ppapi/proxy/interface_proxy.h"
#include "ppapi/proxy/plugin_globals.h"
#include "ppapi/proxy/plugin_message_filter.h"
#include "ppapi/proxy/plugin_resource_tracker.h"
#include "ppapi/proxy/plugin_var_serialization_rules.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/ppb_instance_proxy.h"
#include "ppapi/proxy/ppp_class_proxy.h"
#include "ppapi/proxy/resource_creation_proxy.h"
#include "ppapi/proxy/resource_message_params.h"
#include "ppapi/shared_impl/ppapi_globals.h"
#include "ppapi/shared_impl/proxy_lock.h"
#include "ppapi/shared_impl/resource.h"

#if defined(OS_POSIX) && !defined(OS_NACL)
#include "base/posix/eintr_wrapper.h"
#include "ipc/ipc_channel_posix.h"
#endif

namespace ppapi {
namespace proxy {

namespace {

typedef std::map<PP_Instance, PluginDispatcher*> InstanceToDispatcherMap;
InstanceToDispatcherMap* g_instance_to_dispatcher = NULL;

typedef std::set<PluginDispatcher*> DispatcherSet;
DispatcherSet* g_live_dispatchers = NULL;

}  // namespace

InstanceData::InstanceData()
    : is_request_surrounding_text_pending(false),
      should_do_request_surrounding_text(false) {
}

InstanceData::~InstanceData() {
  // Run any pending mouse lock callback to prevent leaks.
  if (mouse_lock_callback.get())
    mouse_lock_callback->Abort();
}

PluginDispatcher::PluginDispatcher(PP_GetInterface_Func get_interface,
                                   const PpapiPermissions& permissions,
                                   bool incognito)
    : Dispatcher(get_interface, permissions),
      plugin_delegate_(NULL),
      received_preferences_(false),
      plugin_dispatcher_id_(0),
      incognito_(incognito) {
  SetSerializationRules(new PluginVarSerializationRules(AsWeakPtr()));

  if (!g_live_dispatchers)
    g_live_dispatchers = new DispatcherSet;
  g_live_dispatchers->insert(this);
}

PluginDispatcher::~PluginDispatcher() {
  PluginGlobals::Get()->plugin_var_tracker()->DidDeleteDispatcher(this);

  if (plugin_delegate_)
    plugin_delegate_->Unregister(plugin_dispatcher_id_);

  g_live_dispatchers->erase(this);
  if (g_live_dispatchers->empty()) {
    delete g_live_dispatchers;
    g_live_dispatchers = NULL;
  }
}

// static
PluginDispatcher* PluginDispatcher::GetForInstance(PP_Instance instance) {
  if (!g_instance_to_dispatcher)
    return NULL;
  InstanceToDispatcherMap::iterator found = g_instance_to_dispatcher->find(
      instance);
  if (found == g_instance_to_dispatcher->end())
    return NULL;
  return found->second;
}

// static
PluginDispatcher* PluginDispatcher::GetForResource(const Resource* resource) {
  return GetForInstance(resource->pp_instance());
}

// static
const void* PluginDispatcher::GetBrowserInterface(const char* interface_name) {
  if (!interface_name) {
    DLOG(WARNING) << "|interface_name| is null. Did you forget to add "
        "the |interface_name()| template function to the interface's C++ "
        "wrapper?";
    return NULL;
  }

  return InterfaceList::GetInstance()->GetInterfaceForPPB(interface_name);
}

// static
void PluginDispatcher::LogWithSource(PP_Instance instance,
                                     PP_LogLevel level,
                                     const std::string& source,
                                     const std::string& value) {
  if (!g_live_dispatchers || !g_instance_to_dispatcher)
    return;

  if (instance) {
    InstanceToDispatcherMap::iterator found =
        g_instance_to_dispatcher->find(instance);
    if (found != g_instance_to_dispatcher->end()) {
      // Send just to this specific dispatcher.
      found->second->Send(new PpapiHostMsg_LogWithSource(
          instance, static_cast<int>(level), source, value));
      return;
    }
  }

  // Instance 0 or invalid, send to all dispatchers.
  for (DispatcherSet::iterator i = g_live_dispatchers->begin();
       i != g_live_dispatchers->end(); ++i) {
    (*i)->Send(new PpapiHostMsg_LogWithSource(
        instance, static_cast<int>(level), source, value));
  }
}

const void* PluginDispatcher::GetPluginInterface(
    const std::string& interface_name) {
  InterfaceMap::iterator found = plugin_interfaces_.find(interface_name);
  if (found == plugin_interfaces_.end()) {
    const void* ret = local_get_interface()(interface_name.c_str());
    plugin_interfaces_.insert(std::make_pair(interface_name, ret));
    return ret;
  }
  return found->second;
}

bool PluginDispatcher::InitPluginWithChannel(
    PluginDelegate* delegate,
    base::ProcessId peer_pid,
    const IPC::ChannelHandle& channel_handle,
    bool is_client) {
  if (!Dispatcher::InitWithChannel(delegate, peer_pid, channel_handle,
                                   is_client))
    return false;
  plugin_delegate_ = delegate;
  plugin_dispatcher_id_ = plugin_delegate_->Register(this);

  sync_filter_ = new IPC::SyncMessageFilter(delegate->GetShutdownEvent());
  channel()->AddFilter(sync_filter_.get());

  // The message filter will intercept and process certain messages directly
  // on the I/O thread.
  channel()->AddFilter(
      new PluginMessageFilter(delegate->GetGloballySeenInstanceIDSet()));
  return true;
}

bool PluginDispatcher::IsPlugin() const {
  return true;
}

bool PluginDispatcher::SendMessage(IPC::Message* msg) {
  // Currently we need to choose between two different mechanisms for sending.
  // On the main thread we use the regular dispatch Send() method, on another
  // thread we use SyncMessageFilter.
  if (PpapiGlobals::Get()->GetMainThreadMessageLoop()->BelongsToCurrentThread())
    return Dispatcher::Send(msg);
  return sync_filter_->Send(msg);
}

bool PluginDispatcher::Send(IPC::Message* msg) {
  TRACE_EVENT2("ppapi proxy", "PluginDispatcher::Send",
               "Class", IPC_MESSAGE_ID_CLASS(msg->type()),
               "Line", IPC_MESSAGE_ID_LINE(msg->type()));
  // We always want plugin->renderer messages to arrive in-order. If some sync
  // and some async messages are sent in response to a synchronous
  // renderer->plugin call, the sync reply will be processed before the async
  // reply, and everything will be confused.
  //
  // Allowing all async messages to unblock the renderer means more reentrancy
  // there but gives correct ordering.
  //
  // We don't want reply messages to unblock however, as they will potentially
  // end up on the wrong queue - see crbug.com/122443
  if (!msg->is_reply())
    msg->set_unblock(true);
  if (msg->is_sync()) {
    // Synchronous messages might be re-entrant, so we need to drop the lock.
    ProxyAutoUnlock unlock;
    return SendMessage(msg);
  }
  return SendMessage(msg);
}

bool PluginDispatcher::OnMessageReceived(const IPC::Message& msg) {
  // We need to grab the proxy lock to ensure that we don't collide with the
  // plugin making pepper calls on a different thread.
  ProxyAutoLock lock;
  TRACE_EVENT2("ppapi proxy", "PluginDispatcher::OnMessageReceived",
               "Class", IPC_MESSAGE_ID_CLASS(msg.type()),
               "Line", IPC_MESSAGE_ID_LINE(msg.type()));

  if (msg.routing_id() == MSG_ROUTING_CONTROL) {
    // Handle some plugin-specific control messages.
    bool handled = true;
    IPC_BEGIN_MESSAGE_MAP(PluginDispatcher, msg)
      IPC_MESSAGE_HANDLER(PpapiPluginMsg_ResourceReply, OnMsgResourceReply)
      IPC_MESSAGE_HANDLER(PpapiMsg_SupportsInterface, OnMsgSupportsInterface)
      IPC_MESSAGE_HANDLER(PpapiMsg_SetPreferences, OnMsgSetPreferences)
      IPC_MESSAGE_UNHANDLED(handled = false);
    IPC_END_MESSAGE_MAP()
    if (handled)
      return true;
  }
  return Dispatcher::OnMessageReceived(msg);
}

void PluginDispatcher::OnChannelError() {
  Dispatcher::OnChannelError();

  // The renderer has crashed or exited. This channel and all instances
  // associated with it are no longer valid.
  ForceFreeAllInstances();
  // TODO(brettw) free resources too!
  delete this;
}

void PluginDispatcher::DidCreateInstance(PP_Instance instance) {
  if (!g_instance_to_dispatcher)
    g_instance_to_dispatcher = new InstanceToDispatcherMap;
  (*g_instance_to_dispatcher)[instance] = this;

  instance_map_[instance] = InstanceData();
}

void PluginDispatcher::DidDestroyInstance(PP_Instance instance) {
  InstanceDataMap::iterator it = instance_map_.find(instance);
  if (it != instance_map_.end())
    instance_map_.erase(it);

  if (g_instance_to_dispatcher) {
    InstanceToDispatcherMap::iterator found = g_instance_to_dispatcher->find(
        instance);
    if (found != g_instance_to_dispatcher->end()) {
      DCHECK(found->second == this);
      g_instance_to_dispatcher->erase(found);
    } else {
      NOTREACHED();
    }
  }
}

InstanceData* PluginDispatcher::GetInstanceData(PP_Instance instance) {
  InstanceDataMap::iterator it = instance_map_.find(instance);
  return (it == instance_map_.end()) ? NULL : &it->second;
}

thunk::PPB_Instance_API* PluginDispatcher::GetInstanceAPI() {
  return static_cast<PPB_Instance_Proxy*>(
      GetInterfaceProxy(API_ID_PPB_INSTANCE));
}

thunk::ResourceCreationAPI* PluginDispatcher::GetResourceCreationAPI() {
  return static_cast<ResourceCreationProxy*>(
      GetInterfaceProxy(API_ID_RESOURCE_CREATION));
}

// static
void PluginDispatcher::DispatchResourceReply(
    const ppapi::proxy::ResourceMessageReplyParams& reply_params,
    const IPC::Message& nested_msg) {
  // We need to grab the proxy lock to ensure that we don't collide with the
  // plugin making pepper calls on a different thread.
  ProxyAutoLock lock;
  LockedDispatchResourceReply(reply_params, nested_msg);
}

void PluginDispatcher::ForceFreeAllInstances() {
  if (!g_instance_to_dispatcher)
    return;

  // Iterating will remove each item from the map, so we need to make a copy
  // to avoid things changing out from under is.
  InstanceToDispatcherMap temp_map = *g_instance_to_dispatcher;
  for (InstanceToDispatcherMap::iterator i = temp_map.begin();
       i != temp_map.end(); ++i) {
    if (i->second == this) {
      // Synthesize an "instance destroyed" message, this will notify the
      // plugin and also remove it from our list of tracked plugins.
      PpapiMsg_PPPInstance_DidDestroy msg(API_ID_PPP_INSTANCE, i->first);
      OnMessageReceived(msg);
    }
  }
}

void PluginDispatcher::OnMsgResourceReply(
    const ppapi::proxy::ResourceMessageReplyParams& reply_params,
    const IPC::Message& nested_msg) {
  LockedDispatchResourceReply(reply_params, nested_msg);
}

void PluginDispatcher::OnMsgSupportsInterface(
    const std::string& interface_name,
    bool* result) {
  *result = !!GetPluginInterface(interface_name);

  // Do fallback for PPP_Instance. This is a hack here and if we have more
  // cases like this it should be generalized. The PPP_Instance proxy always
  // proxies the 1.1 interface, and then does fallback to 1.0 inside the
  // plugin process (see PPP_Instance_Proxy). So here we return true for
  // supporting the 1.1 interface if either 1.1 or 1.0 is supported.
  if (!*result && interface_name == PPP_INSTANCE_INTERFACE)
    *result = !!GetPluginInterface(PPP_INSTANCE_INTERFACE_1_0);
}

void PluginDispatcher::OnMsgSetPreferences(const Preferences& prefs) {
  // The renderer may send us preferences more than once (currently this
  // happens every time a new plugin instance is created). Since we don't have
  // a way to signal to the plugin that the preferences have changed, changing
  // the default fonts and such in the middle of a running plugin could be
  // confusing to it. As a result, we never allow the preferences to be changed
  // once they're set. The user will have to restart to get new font prefs
  // propogated to plugins.
  if (!received_preferences_) {
    received_preferences_ = true;
    preferences_ = prefs;
  }
}

// static
void PluginDispatcher::LockedDispatchResourceReply(
    const ppapi::proxy::ResourceMessageReplyParams& reply_params,
    const IPC::Message& nested_msg) {
  Resource* resource = PpapiGlobals::Get()->GetResourceTracker()->GetResource(
      reply_params.pp_resource());
  if (!resource) {
    DLOG_IF(INFO, reply_params.sequence() != 0)
        << "Pepper resource reply message received but the resource doesn't "
           "exist (probably has been destroyed).";
    return;
  }
  resource->OnReplyReceived(reply_params, nested_msg);
}

}  // namespace proxy
}  // namespace ppapi
