1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright 2013 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)
5ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/child/npapi/npobject_util.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
8ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/child/npapi/np_channel_base.h"
9ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/child/npapi/npobject_proxy.h"
10ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/child/npapi/plugin_host.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/child/plugin_messages.h"
127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebBindings.h"
1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "third_party/npapi/bindings/nphostapi.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebBindings;
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// true if the current process is a plugin process, false otherwise.
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool g_plugin_process;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(ENABLE_PLUGINS)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The next 7 functions are called by the plugin code when it's using the
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NPObject.  Plugins always ignore the functions in NPClass (except allocate
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and deallocate), and instead just use the function pointers that were
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// passed in NPInitialize.
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// When the renderer interacts with an NPObject from the plugin, it of course
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// uses the function pointers in its NPClass structure.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool NPN_HasMethodPatch(NPP npp,
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               NPObject *npobj,
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               NPIdentifier methodName) {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NPObjectProxy::NPHasMethod(npobj, methodName);
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool NPN_InvokePatch(NPP npp, NPObject *npobj,
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            NPIdentifier methodName,
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const NPVariant *args,
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            uint32_t argCount,
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            NPVariant *result) {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NPObjectProxy::NPInvokePrivate(npp, npobj, false, methodName, args,
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        argCount, result);
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool NPN_InvokeDefaultPatch(NPP npp,
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   NPObject *npobj,
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const NPVariant *args,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   uint32_t argCount,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   NPVariant *result) {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NPObjectProxy::NPInvokePrivate(npp, npobj, true, 0, args, argCount,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        result);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool NPN_HasPropertyPatch(NPP npp,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 NPObject *npobj,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 NPIdentifier propertyName) {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NPObjectProxy::NPHasProperty(npobj, propertyName);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool NPN_GetPropertyPatch(NPP npp,
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 NPObject *npobj,
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 NPIdentifier propertyName,
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 NPVariant *result) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NPObjectProxy::NPGetProperty(npobj, propertyName, result);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool NPN_SetPropertyPatch(NPP npp,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 NPObject *npobj,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 NPIdentifier propertyName,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const NPVariant *value) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NPObjectProxy::NPSetProperty(npobj, propertyName, value);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool NPN_RemovePropertyPatch(NPP npp,
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    NPObject *npobj,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    NPIdentifier propertyName) {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NPObjectProxy::NPRemoveProperty(npobj, propertyName);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool NPN_EvaluatePatch(NPP npp,
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              NPObject *npobj,
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              NPString *script,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              NPVariant *result) {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NPObjectProxy::NPNEvaluate(npp, npobj, script, result);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void NPN_SetExceptionPatch(NPObject *obj, const NPUTF8 *message) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string message_str(message);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsPluginProcess()) {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NPChannelBase* renderer_channel = NPChannelBase::GetCurrentChannel();
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (renderer_channel)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      renderer_channel->Send(new PluginHostMsg_SetException(message_str));
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebBindings::setException(obj, message_str.c_str());
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool NPN_EnumeratePatch(NPP npp, NPObject *obj,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               NPIdentifier **identifier, uint32_t *count) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NPObjectProxy::NPNEnumerate(obj, identifier, count);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The overrided table of functions provided to the plugin.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NPNetscapeFuncs *GetHostFunctions() {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool init = false;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static NPNetscapeFuncs host_funcs;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (init)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return &host_funcs;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(&host_funcs, 0, sizeof(host_funcs));
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_funcs.invoke = NPN_InvokePatch;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_funcs.invokeDefault = NPN_InvokeDefaultPatch;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_funcs.evaluate = NPN_EvaluatePatch;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_funcs.getproperty = NPN_GetPropertyPatch;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_funcs.setproperty = NPN_SetPropertyPatch;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_funcs.removeproperty = NPN_RemovePropertyPatch;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_funcs.hasproperty = NPN_HasPropertyPatch;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_funcs.hasmethod = NPN_HasMethodPatch;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_funcs.setexception = NPN_SetExceptionPatch;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_funcs.enumerate = NPN_EnumeratePatch;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  init = true;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return &host_funcs;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif  // defined(ENABLE_PLUGINS)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(ENABLE_PLUGINS)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PatchNPNFunctions() {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_plugin_process = true;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NPNetscapeFuncs* funcs = GetHostFunctions();
134ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  PluginHost::Singleton()->PatchNPNetscapeFuncs(funcs);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsPluginProcess() {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_plugin_process;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CreateNPIdentifierParam(NPIdentifier id, NPIdentifier_Param* param) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  param->identifier = id;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NPIdentifier CreateNPIdentifier(const NPIdentifier_Param& param) {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return param.identifier;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CreateNPVariantParam(const NPVariant& variant,
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          NPChannelBase* channel,
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          NPVariant_Param* param,
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          bool release,
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          int render_view_id,
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const GURL& page_url) {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (variant.type) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NPVariantType_Void:
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      param->type = NPVARIANT_PARAM_VOID;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NPVariantType_Null:
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      param->type = NPVARIANT_PARAM_NULL;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NPVariantType_Bool:
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      param->type = NPVARIANT_PARAM_BOOL;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      param->bool_value = variant.value.boolValue;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NPVariantType_Int32:
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      param->type = NPVARIANT_PARAM_INT;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      param->int_value = variant.value.intValue;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NPVariantType_Double:
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      param->type = NPVARIANT_PARAM_DOUBLE;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      param->double_value = variant.value.doubleValue;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NPVariantType_String:
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      param->type = NPVARIANT_PARAM_STRING;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (variant.value.stringValue.UTF8Length) {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        param->string_value.assign(variant.value.stringValue.UTF8Characters,
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   variant.value.stringValue.UTF8Length);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NPVariantType_Object: {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (variant.value.objectValue->_class == NPObjectProxy::npclass()) {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        param->type = NPVARIANT_PARAM_RECEIVER_OBJECT_ROUTING_ID;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NPObjectProxy* proxy =
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            NPObjectProxy::GetProxy(variant.value.objectValue);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DCHECK(proxy);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        param->npobject_routing_id = proxy->route_id();
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Don't release, because our original variant is the same as our proxy.
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        release = false;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // The channel could be NULL if there was a channel error. The caller's
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Send call will fail anyways.
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (channel) {
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // NPObjectStub adds its own reference to the NPObject it owns, so if
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // we were supposed to release the corresponding variant
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // (release==true), we should still do that.
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          param->type = NPVARIANT_PARAM_SENDER_OBJECT_ROUTING_ID;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          int route_id = channel->GetExistingRouteForNPObjectStub(
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              variant.value.objectValue);
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          if (route_id != MSG_ROUTING_NONE) {
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            param->npobject_routing_id = route_id;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          } else {
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            route_id = channel->GenerateRouteID();
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            new NPObjectStub(
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                variant.value.objectValue, channel, route_id, render_view_id,
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                page_url);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            param->npobject_routing_id = route_id;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          }
210eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
211eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          // Include the object's owner.
212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          NPP owner = WebBindings::getObjectOwner(variant.value.objectValue);
213eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          param->npobject_owner_id =
214eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              channel->GetExistingRouteForNPObjectOwner(owner);
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          param->type = NPVARIANT_PARAM_VOID;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (release)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebBindings::releaseVariantValue(const_cast<NPVariant*>(&variant));
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CreateNPVariant(const NPVariant_Param& param,
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     NPChannelBase* channel,
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     NPVariant* result,
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     int render_view_id,
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const GURL& page_url) {
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (param.type) {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NPVARIANT_PARAM_VOID:
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result->type = NPVariantType_Void;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NPVARIANT_PARAM_NULL:
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result->type = NPVariantType_Null;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NPVARIANT_PARAM_BOOL:
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result->type = NPVariantType_Bool;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result->value.boolValue = param.bool_value;
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NPVARIANT_PARAM_INT:
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result->type = NPVariantType_Int32;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result->value.intValue = param.int_value;
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NPVARIANT_PARAM_DOUBLE:
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result->type = NPVariantType_Double;
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result->value.doubleValue = param.double_value;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NPVARIANT_PARAM_STRING: {
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result->type = NPVariantType_String;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      void* buffer = malloc(param.string_value.size());
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size_t size = param.string_value.size();
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result->value.stringValue.UTF8Characters = static_cast<NPUTF8*>(buffer);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      memcpy(buffer, param.string_value.c_str(), size);
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result->value.stringValue.UTF8Length = static_cast<int>(size);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NPVARIANT_PARAM_SENDER_OBJECT_ROUTING_ID: {
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result->type = NPVariantType_Object;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NPObject* object =
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          channel->GetExistingNPObjectProxy(param.npobject_routing_id);
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (object) {
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        WebBindings::retainObject(object);
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        result->value.objectValue = object;
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
270eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        NPP owner =
271eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            channel->GetExistingNPObjectOwner(param.npobject_owner_id);
272eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        // TODO(wez): Once NPObject tracking lands in Blink, check |owner| and
273eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        // return NPVariantType_Void if it is NULL.
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        result->value.objectValue =
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            NPObjectProxy::Create(channel,
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  param.npobject_routing_id,
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  render_view_id,
278eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                  page_url,
279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                  owner);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NPVARIANT_PARAM_RECEIVER_OBJECT_ROUTING_ID: {
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NPObjectBase* npobject_base =
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          channel->GetNPObjectListenerForRoute(param.npobject_routing_id);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!npobject_base) {
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DLOG(WARNING) << "Invalid routing id passed in"
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      << param.npobject_routing_id;
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(npobject_base->GetUnderlyingNPObject() != NULL);
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result->type = NPVariantType_Object;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result->value.objectValue = npobject_base->GetUnderlyingNPObject();
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WebBindings::retainObject(result->value.objectValue);
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
306