15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 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)
5bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/renderer/pepper/npapi_glue.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
97d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string_util.h"
10bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/renderer/pepper/host_array_buffer_var.h"
11bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/renderer/pepper/host_globals.h"
12bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/renderer/pepper/host_var_tracker.h"
13bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/renderer/pepper/npobject_var.h"
1458e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
15bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/renderer/pepper/plugin_module.h"
16bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/renderer/pepper/plugin_object.h"
177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "ppapi/c/pp_var.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/npapi/bindings/npapi.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/npapi/bindings/npruntime.h"
207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebBindings.h"
217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "third_party/WebKit/public/web/WebDocument.h"
227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "third_party/WebKit/public/web/WebElement.h"
237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "third_party/WebKit/public/web/WebFrame.h"
247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "third_party/WebKit/public/web/WebPluginContainer.h"
257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "v8/include/v8.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ppapi::NPObjectVar;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ppapi::PpapiGlobals;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ppapi::StringVar;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ppapi::Var;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebArrayBuffer;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebBindings;
337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing WebKit::WebPluginContainer;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdochnamespace content {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInvalidPluginValue[] = "Error: Plugin returned invalid value.";
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben MurdochPP_Var NPObjectToPPVarImpl(PepperPluginInstanceImpl* instance,
427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                           NPObject* object,
437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                           v8::Local<v8::Context> context) {
447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(object);
457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (context.IsEmpty())
467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return PP_MakeUndefined();
477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  v8::Context::Scope context_scope(context);
487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  WebArrayBuffer buffer;
507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // TODO(dmichael): Should I protect against duplicate Vars representing the
517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // same array buffer? It's probably not worth the trouble, since it will only
527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // affect in-process plugins.
537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (WebBindings::getArrayBuffer(object, &buffer)) {
547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    scoped_refptr<HostArrayBufferVar> buffer_var(
557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        new HostArrayBufferVar(buffer));
567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return buffer_var->GetPPVar();
577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scoped_refptr<NPObjectVar> object_var(
597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HostGlobals::Get()->host_var_tracker()->NPObjectVarForNPObject(
607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          instance->pp_instance(), object));
617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!object_var.get()) {  // No object for this module yet, make a new one.
627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    object_var = new NPObjectVar(instance->pp_instance(), object);
637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return object_var->GetPPVar();
657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Utilities -------------------------------------------------------------------
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PPVarToNPVariant(PP_Var var, NPVariant* result) {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (var.type) {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_UNDEFINED:
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      VOID_TO_NPVARIANT(*result);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_NULL:
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL_TO_NPVARIANT(*result);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_BOOL:
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BOOLEAN_TO_NPVARIANT(var.value.as_bool, *result);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_INT32:
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      INT32_TO_NPVARIANT(var.value.as_int, *result);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_DOUBLE:
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DOUBLE_TO_NPVARIANT(var.value.as_double, *result);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_STRING: {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      StringVar* string = StringVar::FromPPVar(var);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!string) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        VOID_TO_NPVARIANT(*result);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& value = string->value();
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      char* c_string = static_cast<char*>(malloc(value.size()));
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      memcpy(c_string, value.data(), value.size());
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      STRINGN_TO_NPVARIANT(c_string, value.size(), *result);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_OBJECT: {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scoped_refptr<NPObjectVar> object(NPObjectVar::FromPPVar(var));
103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (!object.get()) {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        VOID_TO_NPVARIANT(*result);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OBJECT_TO_NPVARIANT(WebBindings::retainObject(object->np_object()),
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          *result);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The following types are not supported for use with PPB_Var_Deprecated,
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // because PPB_Var_Deprecated is only for trusted plugins, and the trusted
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // plugins we have don't need these types. We can add support in the future
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // if it becomes necessary.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_ARRAY:
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_DICTIONARY:
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_ARRAY_BUFFER:
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      VOID_TO_NPVARIANT(*result);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12458e6fbe4ee35d65e14b626c557d37565bf8ad179Ben MurdochPP_Var NPVariantToPPVar(PepperPluginInstanceImpl* instance,
125bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch                        const NPVariant* variant) {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (variant->type) {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NPVariantType_Void:
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return PP_MakeUndefined();
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NPVariantType_Null:
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return PP_MakeNull();
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NPVariantType_Bool:
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return PP_MakeBool(PP_FromBool(NPVARIANT_TO_BOOLEAN(*variant)));
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NPVariantType_Int32:
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return PP_MakeInt32(NPVARIANT_TO_INT32(*variant));
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NPVariantType_Double:
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return PP_MakeDouble(NPVARIANT_TO_DOUBLE(*variant));
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NPVariantType_String:
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return StringVar::StringToPPVar(
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          NPVARIANT_TO_STRING(*variant).UTF8Characters,
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          NPVARIANT_TO_STRING(*variant).UTF8Length);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NPVariantType_Object:
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return NPObjectToPPVar(instance, NPVARIANT_TO_OBJECT(*variant));
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_MakeUndefined();
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NPIdentifier PPVarToNPIdentifier(PP_Var var) {
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (var.type) {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_STRING: {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      StringVar* string = StringVar::FromPPVar(var);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!string)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return NULL;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return WebBindings::getStringIdentifier(string->value().c_str());
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_INT32:
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return WebBindings::getIntIdentifier(var.value.as_int);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return NULL;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Var NPIdentifierToPPVar(NPIdentifier id) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const NPUTF8* string_value = NULL;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32_t int_value = 0;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_string = false;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebBindings::extractIdentifierData(id, string_value, int_value, is_string);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_string)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return StringVar::StringToPPVar(string_value);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_MakeInt32(int_value);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17458e6fbe4ee35d65e14b626c557d37565bf8ad179Ben MurdochPP_Var NPObjectToPPVar(PepperPluginInstanceImpl* instance, NPObject* object) {
1757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  WebPluginContainer* container = instance->container();
1767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // It's possible that container() is NULL if the plugin has been removed from
1777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // the DOM (but the PluginInstance is not destroyed yet).
1787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!container)
1797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return PP_MakeUndefined();
1807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  v8::HandleScope scope(instance->GetIsolate());
1817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  v8::Local<v8::Context> context =
1827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      container->element().document().frame()->mainWorldScriptContext();
1837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return NPObjectToPPVarImpl(instance, object, context);
1847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
18658e6fbe4ee35d65e14b626c557d37565bf8ad179Ben MurdochPP_Var NPObjectToPPVarForTest(PepperPluginInstanceImpl* instance,
18758e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch                              NPObject* object) {
1887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  v8::Isolate* test_isolate = v8::Isolate::New();
1897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PP_Var result = PP_MakeUndefined();
1907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  {
1917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    v8::HandleScope scope(test_isolate);
1927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    v8::Isolate::Scope isolate_scope(test_isolate);
1937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    v8::Local<v8::Context> context = v8::Context::New(test_isolate);
1947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    result = NPObjectToPPVarImpl(instance, object, context);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  test_isolate->Dispose();
1977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return result;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PPResultAndExceptionToNPResult ----------------------------------------------
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPResultAndExceptionToNPResult::PPResultAndExceptionToNPResult(
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NPObject* object_var,
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NPVariant* np_result)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : object_var_(object_var),
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      np_result_(np_result),
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      exception_(PP_MakeUndefined()),
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      success_(false),
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      checked_exception_(false) {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPResultAndExceptionToNPResult::~PPResultAndExceptionToNPResult() {
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The user should have called SetResult or CheckExceptionForNoResult
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // before letting this class go out of scope, or the exception will have
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // been lost.
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(checked_exception_);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(exception_);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Call this with the return value of the PPAPI function. It will convert
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the result to the NPVariant output parameter and pass any exception on to
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the JS engine. It will update the success flag and return it.
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PPResultAndExceptionToNPResult::SetResult(PP_Var result) {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!checked_exception_);  // Don't call more than once.
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(np_result_);  // Should be expecting a result.
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  checked_exception_ = true;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (has_exception()) {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ThrowException();
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    success_ = false;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (!PPVarToNPVariant(result, np_result_)) {
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebBindings::setException(object_var_, kInvalidPluginValue);
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    success_ = false;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    success_ = true;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No matter what happened, we need to release the reference to the
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // value passed in. On success, a reference to this value will be in
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the np_result_.
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(result);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return success_;
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Call this after calling a PPAPI function that could have set the
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// exception. It will pass the exception on to the JS engine and update
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the success flag.
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The success flag will be returned.
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PPResultAndExceptionToNPResult::CheckExceptionForNoResult() {
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!checked_exception_);  // Don't call more than once.
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!np_result_);  // Can't have a result when doing this.
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  checked_exception_ = true;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (has_exception()) {
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ThrowException();
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    success_ = false;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  success_ = true;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Call this to ignore any exception. This prevents the DCHECK from failing
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the destructor.
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PPResultAndExceptionToNPResult::IgnoreException() {
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  checked_exception_ = true;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Throws the current exception to JS. The exception must be set.
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PPResultAndExceptionToNPResult::ThrowException() {
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StringVar* string = StringVar::FromPPVar(exception_);
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (string)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebBindings::setException(object_var_, string->value().c_str());
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PPVarArrayFromNPVariantArray ------------------------------------------------
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPVarArrayFromNPVariantArray::PPVarArrayFromNPVariantArray(
28358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    PepperPluginInstanceImpl* instance,
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t size,
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const NPVariant* variants)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : size_(size) {
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (size_ > 0) {
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    array_.reset(new PP_Var[size_]);
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < size_; i++)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      array_[i] = NPVariantToPPVar(instance, &variants[i]);
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPVarArrayFromNPVariantArray::~PPVarArrayFromNPVariantArray() {
2954311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch  ppapi::VarTracker* var_tracker = PpapiGlobals::Get()->GetVarTracker();
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < size_; i++)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var_tracker->ReleaseVar(array_[i]);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PPVarFromNPObject -----------------------------------------------------------
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben MurdochPPVarFromNPObject::PPVarFromNPObject(PepperPluginInstanceImpl* instance,
303bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch                                     NPObject* object)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : var_(NPObjectToPPVar(instance, object)) {
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPVarFromNPObject::~PPVarFromNPObject() {
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(var_);
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NPObjectAccessorWithIdentifier ----------------------------------------------
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NPObjectAccessorWithIdentifier::NPObjectAccessorWithIdentifier(
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NPObject* object,
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NPIdentifier identifier,
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool allow_integer_identifier)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : object_(PluginObject::FromNPObject(object)),
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      identifier_(PP_MakeUndefined()) {
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (object_) {
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    identifier_ = NPIdentifierToPPVar(identifier);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (identifier_.type == PP_VARTYPE_INT32 && !allow_integer_identifier)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      identifier_.type = PP_VARTYPE_UNDEFINED;  // Mark it invalid.
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NPObjectAccessorWithIdentifier::~NPObjectAccessorWithIdentifier() {
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(identifier_);
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TryCatch --------------------------------------------------------------------
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TryCatch::TryCatch(PP_Var* exception)
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : has_exception_(exception && exception->type != PP_VARTYPE_UNDEFINED),
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      exception_(exception) {
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebBindings::pushExceptionHandler(&TryCatch::Catch, this);
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TryCatch::~TryCatch() {
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebBindings::popExceptionHandler();
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TryCatch::SetException(const char* message) {
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!has_exception()) {
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    has_exception_ = true;
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exception_) {
3464311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch      *exception_ = ppapi::StringVar::StringToPPVar(message, strlen(message));
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TryCatch::Catch(void* self, const char* message) {
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static_cast<TryCatch*>(self)->SetException(message);
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35658e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch}  // namespace content
357