// 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_var_tracker.h"

#include <stddef.h>

#include "base/memory/ref_counted.h"
#include "base/memory/singleton.h"
#include "ipc/ipc_message.h"
#include "ppapi/c/dev/ppp_class_deprecated.h"
#include "ppapi/c/ppb_var.h"
#include "ppapi/proxy/file_system_resource.h"
#include "ppapi/proxy/media_stream_audio_track_resource.h"
#include "ppapi/proxy/media_stream_video_track_resource.h"
#include "ppapi/proxy/plugin_array_buffer_var.h"
#include "ppapi/proxy/plugin_dispatcher.h"
#include "ppapi/proxy/plugin_globals.h"
#include "ppapi/proxy/plugin_resource_var.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/proxy_object_var.h"
#include "ppapi/shared_impl/api_id.h"
#include "ppapi/shared_impl/ppapi_globals.h"
#include "ppapi/shared_impl/proxy_lock.h"
#include "ppapi/shared_impl/resource_tracker.h"
#include "ppapi/shared_impl/var.h"

namespace ppapi {
namespace proxy {

namespace {

Connection GetConnectionForInstance(PP_Instance instance) {
  PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
  DCHECK(dispatcher);
  return Connection(PluginGlobals::Get()->GetBrowserSender(),
                    dispatcher->sender());
}

}  // namespace

PluginVarTracker::HostVar::HostVar(PluginDispatcher* d, int32_t i)
    : dispatcher(d), host_object_id(i) {}

bool PluginVarTracker::HostVar::operator<(const HostVar& other) const {
  if (dispatcher < other.dispatcher)
    return true;
  if (other.dispatcher < dispatcher)
    return false;
  return host_object_id < other.host_object_id;
}

PluginVarTracker::PluginVarTracker() : VarTracker(THREAD_SAFE) {
}

PluginVarTracker::~PluginVarTracker() {
}

PP_Var PluginVarTracker::ReceiveObjectPassRef(const PP_Var& host_var,
                                              PluginDispatcher* dispatcher) {
  CheckThreadingPreconditions();
  DCHECK(host_var.type == PP_VARTYPE_OBJECT);

  // Get the object.
  scoped_refptr<ProxyObjectVar> object(
      FindOrMakePluginVarFromHostVar(host_var, dispatcher));

  // Actually create the PP_Var, this will add all the tracking info but not
  // adjust any refcounts.
  PP_Var ret = GetOrCreateObjectVarID(object.get());

  VarInfo& info = GetLiveVar(ret)->second;
  if (info.ref_count > 0) {
    // We already had a reference to it before. That means the renderer now has
    // two references on our behalf. We want to transfer that extra reference
    // to our list. This means we addref in the plugin, and release the extra
    // one in the renderer.
    SendReleaseObjectMsg(*object.get());
  }
  info.ref_count++;
  return ret;
}

PP_Var PluginVarTracker::TrackObjectWithNoReference(
    const PP_Var& host_var,
    PluginDispatcher* dispatcher) {
  CheckThreadingPreconditions();
  DCHECK(host_var.type == PP_VARTYPE_OBJECT);

  // Get the object.
  scoped_refptr<ProxyObjectVar> object(
      FindOrMakePluginVarFromHostVar(host_var, dispatcher));

  // Actually create the PP_Var, this will add all the tracking info but not
  // adjust any refcounts.
  PP_Var ret = GetOrCreateObjectVarID(object.get());

  VarInfo& info = GetLiveVar(ret)->second;
  info.track_with_no_reference_count++;
  return ret;
}

void PluginVarTracker::StopTrackingObjectWithNoReference(
    const PP_Var& plugin_var) {
  CheckThreadingPreconditions();
  DCHECK(plugin_var.type == PP_VARTYPE_OBJECT);

  VarMap::iterator found = GetLiveVar(plugin_var);
  if (found == live_vars_.end()) {
    NOTREACHED();
    return;
  }

  DCHECK(found->second.track_with_no_reference_count > 0);
  found->second.track_with_no_reference_count--;
  DeleteObjectInfoIfNecessary(found);
}

PP_Var PluginVarTracker::GetHostObject(const PP_Var& plugin_object) const {
  CheckThreadingPreconditions();
  if (plugin_object.type != PP_VARTYPE_OBJECT) {
    NOTREACHED();
    return PP_MakeUndefined();
  }

  Var* var = GetVar(plugin_object);
  ProxyObjectVar* object = var->AsProxyObjectVar();
  if (!object) {
    NOTREACHED();
    return PP_MakeUndefined();
  }

  // Make a var with the host ID.
  PP_Var ret = { PP_VARTYPE_OBJECT };
  ret.value.as_id = object->host_var_id();
  return ret;
}

PluginDispatcher* PluginVarTracker::DispatcherForPluginObject(
    const PP_Var& plugin_object) const {
  CheckThreadingPreconditions();
  if (plugin_object.type != PP_VARTYPE_OBJECT)
    return NULL;

  VarMap::const_iterator found = GetLiveVar(plugin_object);
  if (found == live_vars_.end())
    return NULL;

  ProxyObjectVar* object = found->second.var->AsProxyObjectVar();
  if (!object)
    return NULL;
  return object->dispatcher();
}

void PluginVarTracker::ReleaseHostObject(PluginDispatcher* dispatcher,
                                         const PP_Var& host_object) {
  CheckThreadingPreconditions();
  DCHECK(host_object.type == PP_VARTYPE_OBJECT);

  // Convert the host object to a normal var valid in the plugin.
  HostVarToPluginVarMap::iterator found = host_var_to_plugin_var_.find(
      HostVar(dispatcher, static_cast<int32_t>(host_object.value.as_id)));
  if (found == host_var_to_plugin_var_.end()) {
    NOTREACHED();
    return;
  }

  // Now just release the object given the plugin var ID.
  ReleaseVar(found->second);
}

PP_Var PluginVarTracker::MakeResourcePPVarFromMessage(
    PP_Instance instance,
    const IPC::Message& creation_message,
    int pending_renderer_id,
    int pending_browser_id) {
  switch (creation_message.type()) {
    case PpapiPluginMsg_FileSystem_CreateFromPendingHost::ID: {
      DCHECK(pending_renderer_id);
      DCHECK(pending_browser_id);
      PP_FileSystemType file_system_type;
      if (!UnpackMessage<PpapiPluginMsg_FileSystem_CreateFromPendingHost>(
               creation_message, &file_system_type)) {
        NOTREACHED() << "Invalid message of type "
                        "PpapiPluginMsg_FileSystem_CreateFromPendingHost";
        return PP_MakeNull();
      }
      // Create a plugin-side resource and attach it to the host resource.
      // Note: This only makes sense when the plugin is out of process (which
      // should always be true when passing resource vars).
      PP_Resource pp_resource =
          (new FileSystemResource(GetConnectionForInstance(instance),
                                  instance,
                                  pending_renderer_id,
                                  pending_browser_id,
                                  file_system_type))->GetReference();
      return MakeResourcePPVar(pp_resource);
    }
    case PpapiPluginMsg_MediaStreamAudioTrack_CreateFromPendingHost::ID: {
      DCHECK(pending_renderer_id);
      std::string track_id;
      if (!UnpackMessage<
              PpapiPluginMsg_MediaStreamAudioTrack_CreateFromPendingHost>(
          creation_message, &track_id)) {
        NOTREACHED() <<
            "Invalid message of type "
            "PpapiPluginMsg_MediaStreamAudioTrack_CreateFromPendingHost";
        return PP_MakeNull();
      }
      PP_Resource pp_resource =
          (new MediaStreamAudioTrackResource(GetConnectionForInstance(instance),
                                             instance,
                                             pending_renderer_id,
                                             track_id))->GetReference();
      return MakeResourcePPVar(pp_resource);
    }
    case PpapiPluginMsg_MediaStreamVideoTrack_CreateFromPendingHost::ID: {
      DCHECK(pending_renderer_id);
      std::string track_id;
      if (!UnpackMessage<
              PpapiPluginMsg_MediaStreamVideoTrack_CreateFromPendingHost>(
          creation_message, &track_id)) {
        NOTREACHED() <<
            "Invalid message of type "
            "PpapiPluginMsg_MediaStreamVideoTrack_CreateFromPendingHost";
        return PP_MakeNull();
      }
      PP_Resource pp_resource =
          (new MediaStreamVideoTrackResource(GetConnectionForInstance(instance),
                                             instance,
                                             pending_renderer_id,
                                             track_id))->GetReference();
      return MakeResourcePPVar(pp_resource);
    }
    default: {
      NOTREACHED() << "Creation message has unexpected type "
                   << creation_message.type();
      return PP_MakeNull();
    }
  }
}

ResourceVar* PluginVarTracker::MakeResourceVar(PP_Resource pp_resource) {
  // The resource 0 returns a null resource var.
  if (!pp_resource)
    return new PluginResourceVar();

  ResourceTracker* resource_tracker = PpapiGlobals::Get()->GetResourceTracker();
  ppapi::Resource* resource = resource_tracker->GetResource(pp_resource);
  // A non-existant resource other than 0 returns NULL.
  if (!resource)
    return NULL;
  return new PluginResourceVar(resource);
}

void PluginVarTracker::DidDeleteInstance(PP_Instance instance) {
  // Calling the destructors on plugin objects may in turn release other
  // objects which will mutate the map out from under us. So do a two-step
  // process of identifying the ones to delete, and then delete them.
  //
  // See the comment above user_data_to_plugin_ in the header file. We assume
  // there aren't that many objects so a brute-force search is reasonable.
  std::vector<void*> user_data_to_delete;
  for (UserDataToPluginImplementedVarMap::const_iterator i =
           user_data_to_plugin_.begin();
       i != user_data_to_plugin_.end();
       ++i) {
    if (i->second.instance == instance)
      user_data_to_delete.push_back(i->first);
  }

  for (size_t i = 0; i < user_data_to_delete.size(); i++) {
    UserDataToPluginImplementedVarMap::iterator found =
        user_data_to_plugin_.find(user_data_to_delete[i]);
    if (found == user_data_to_plugin_.end())
      continue;  // Object removed from list while we were iterating.

    if (!found->second.plugin_object_id) {
      // This object is for the freed instance and the plugin is not holding
      // any references to it. Deallocate immediately.
      CallWhileUnlocked(found->second.ppp_class->Deallocate, found->first);
      user_data_to_plugin_.erase(found);
    } else {
      // The plugin is holding refs to this object. We don't want to call
      // Deallocate since the plugin may be depending on those refs to keep
      // its data alive. To avoid crashes in this case, just clear out the
      // instance to mark it and continue. When the plugin refs go to 0,
      // we'll notice there is no instance and call Deallocate.
      found->second.instance = 0;
    }
  }
}

void PluginVarTracker::DidDeleteDispatcher(PluginDispatcher* dispatcher) {
  for (VarMap::iterator it = live_vars_.begin();
       it != live_vars_.end();
       ++it) {
    if (it->second.var.get() == NULL)
      continue;
    ProxyObjectVar* object = it->second.var->AsProxyObjectVar();
    if (object && object->dispatcher() == dispatcher)
      object->clear_dispatcher();
  }
}

ArrayBufferVar* PluginVarTracker::CreateArrayBuffer(uint32_t size_in_bytes) {
  return new PluginArrayBufferVar(size_in_bytes);
}

ArrayBufferVar* PluginVarTracker::CreateShmArrayBuffer(
    uint32_t size_in_bytes,
    base::UnsafeSharedMemoryRegion region) {
  return new PluginArrayBufferVar(size_in_bytes, std::move(region));
}

void PluginVarTracker::PluginImplementedObjectCreated(
    PP_Instance instance,
    const PP_Var& created_var,
    const PPP_Class_Deprecated* ppp_class,
    void* ppp_class_data) {
  PluginImplementedVar p;
  p.ppp_class = ppp_class;
  p.instance = instance;
  p.plugin_object_id = created_var.value.as_id;
  user_data_to_plugin_[ppp_class_data] = p;

  // Link the user data to the object.
  ProxyObjectVar* object = GetVar(created_var)->AsProxyObjectVar();
  object->set_user_data(ppp_class_data);
}

void PluginVarTracker::PluginImplementedObjectDestroyed(void* user_data) {
  UserDataToPluginImplementedVarMap::iterator found =
      user_data_to_plugin_.find(user_data);
  if (found == user_data_to_plugin_.end()) {
    NOTREACHED();
    return;
  }
  user_data_to_plugin_.erase(found);
}

bool PluginVarTracker::IsPluginImplementedObjectAlive(void* user_data) {
  return user_data_to_plugin_.find(user_data) != user_data_to_plugin_.end();
}

bool PluginVarTracker::ValidatePluginObjectCall(
    const PPP_Class_Deprecated* ppp_class,
    void* user_data) {
  UserDataToPluginImplementedVarMap::iterator found =
      user_data_to_plugin_.find(user_data);
  if (found == user_data_to_plugin_.end())
    return false;
  return found->second.ppp_class == ppp_class;
}

int32_t PluginVarTracker::AddVarInternal(Var* var, AddVarRefMode mode) {
  // Normal adding.
  int32_t new_id = VarTracker::AddVarInternal(var, mode);

  // Need to add proxy objects to the host var map.
  ProxyObjectVar* proxy_object = var->AsProxyObjectVar();
  if (proxy_object) {
    HostVar host_var(proxy_object->dispatcher(), proxy_object->host_var_id());
    // TODO(teravest): Change to DCHECK when http://crbug.com/276347 is
    // resolved.
    CHECK(host_var_to_plugin_var_.find(host_var) ==
          host_var_to_plugin_var_.end());  // Adding an object twice, use
                                           // FindOrMakePluginVarFromHostVar.
    host_var_to_plugin_var_[host_var] = new_id;
  }
  return new_id;
}

void PluginVarTracker::TrackedObjectGettingOneRef(VarMap::const_iterator iter) {
  ProxyObjectVar* object = iter->second.var->AsProxyObjectVar();
  if (!object) {
    NOTREACHED();
    return;
  }

  DCHECK(iter->second.ref_count == 0);

  // Got an AddRef for an object we have no existing reference for.
  // We need to tell the browser we've taken a ref. This comes up when the
  // browser passes an object as an input param and holds a ref for us.
  // This must be a sync message since otherwise the "addref" will actually
  // occur after the return to the browser of the sync function that
  // presumably sent the object.
  SendAddRefObjectMsg(*object);
}

void PluginVarTracker::ObjectGettingZeroRef(VarMap::iterator iter) {
  ProxyObjectVar* object = iter->second.var->AsProxyObjectVar();
  if (!object) {
    NOTREACHED();
    return;
  }

  // Notify the host we're no longer holding our ref.
  DCHECK(iter->second.ref_count == 0);
  SendReleaseObjectMsg(*object);

  UserDataToPluginImplementedVarMap::iterator found =
      user_data_to_plugin_.find(object->user_data());
  if (found != user_data_to_plugin_.end()) {
    // This object is implemented in the plugin.
    if (found->second.instance == 0) {
      // Instance is destroyed. This means that we'll never get a Deallocate
      // call from the renderer and we should do so now.
      CallWhileUnlocked(found->second.ppp_class->Deallocate, found->first);
      user_data_to_plugin_.erase(found);
    } else {
      // The plugin is releasing its last reference to an object it implements.
      // Clear the tracking data that links our "plugin implemented object" to
      // the var. If the instance is destroyed and there is no ID, we know that
      // we should just call Deallocate on the object data.
      //
      // See the plugin_object_id declaration for more info.
      found->second.plugin_object_id = 0;
    }
  }

  // This will optionally delete the info from live_vars_.
  VarTracker::ObjectGettingZeroRef(iter);
}

bool PluginVarTracker::DeleteObjectInfoIfNecessary(VarMap::iterator iter) {
  // Get the info before calling the base class's version of this function,
  // which may delete the object.
  ProxyObjectVar* object = iter->second.var->AsProxyObjectVar();
  HostVar host_var(object->dispatcher(), object->host_var_id());

  if (!VarTracker::DeleteObjectInfoIfNecessary(iter))
    return false;

  // Clean up the host var mapping.
  DCHECK(host_var_to_plugin_var_.find(host_var) !=
         host_var_to_plugin_var_.end());
  host_var_to_plugin_var_.erase(host_var);
  return true;
}

PP_Var PluginVarTracker::GetOrCreateObjectVarID(ProxyObjectVar* object) {
  // We can't use object->GetPPVar() because we don't want to affect the
  // refcount, so we have to add everything manually here.
  int32_t var_id = object->GetExistingVarID();
  if (!var_id) {
    var_id = AddVarInternal(object, ADD_VAR_CREATE_WITH_NO_REFERENCE);
    object->AssignVarID(var_id);
  }

  PP_Var ret = { PP_VARTYPE_OBJECT };
  ret.value.as_id = var_id;
  return ret;
}

void PluginVarTracker::SendAddRefObjectMsg(
    const ProxyObjectVar& proxy_object) {
  if (proxy_object.dispatcher()) {
    proxy_object.dispatcher()->Send(new PpapiHostMsg_PPBVar_AddRefObject(
        API_ID_PPB_VAR_DEPRECATED, proxy_object.host_var_id()));
  }
}

void PluginVarTracker::SendReleaseObjectMsg(
    const ProxyObjectVar& proxy_object) {
  if (proxy_object.dispatcher()) {
    proxy_object.dispatcher()->Send(new PpapiHostMsg_PPBVar_ReleaseObject(
        API_ID_PPB_VAR_DEPRECATED, proxy_object.host_var_id()));
  }
}

scoped_refptr<ProxyObjectVar> PluginVarTracker::FindOrMakePluginVarFromHostVar(
    const PP_Var& var,
    PluginDispatcher* dispatcher) {
  DCHECK(var.type == PP_VARTYPE_OBJECT);
  HostVar host_var(dispatcher, var.value.as_id);

  HostVarToPluginVarMap::iterator found =
      host_var_to_plugin_var_.find(host_var);
  if (found == host_var_to_plugin_var_.end()) {
    // Create a new object.
    return scoped_refptr<ProxyObjectVar>(
        new ProxyObjectVar(dispatcher, static_cast<int32_t>(var.value.as_id)));
  }

  // Have this host var, look up the object.
  VarMap::iterator ret = live_vars_.find(found->second);

  // We CHECK here because we currently don't fall back sanely.
  // This may be involved in a NULL dereference. http://crbug.com/276347
  CHECK(ret != live_vars_.end());

  // All objects should be proxy objects.
  DCHECK(ret->second.var->AsProxyObjectVar());
  return scoped_refptr<ProxyObjectVar>(ret->second.var->AsProxyObjectVar());
}

int PluginVarTracker::TrackSharedMemoryRegion(
    PP_Instance instance,
    base::UnsafeSharedMemoryRegion region,
    uint32_t size_in_bytes) {
  NOTREACHED();
  return -1;
}

bool PluginVarTracker::StopTrackingSharedMemoryRegion(
    int id,
    PP_Instance instance,
    base::UnsafeSharedMemoryRegion* region,
    uint32_t* size_in_bytes) {
  NOTREACHED();
  return false;
}

}  // namesace proxy
}  // namespace ppapi
