Move webkit/plugins/ppapi to content/renderer/pepper.

I will change namespaces in a followup as this got very large. Also, I have a temporary dependency from content/common onto content/renderer for PluginModule that I only discovered at the end. I will remove that in a followup.

BUG=263054
[email protected]

Review URL: https://codereview.chromium.org/20165002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@213578 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/content/renderer/pepper/ppb_var_deprecated_impl.cc b/content/renderer/pepper/ppb_var_deprecated_impl.cc
new file mode 100644
index 0000000..cbfc6f9
--- /dev/null
+++ b/content/renderer/pepper/ppb_var_deprecated_impl.cc
@@ -0,0 +1,437 @@
+// 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 "content/renderer/pepper/ppb_var_deprecated_impl.h"
+
+#include <limits>
+
+#include "content/renderer/pepper/common.h"
+#include "content/renderer/pepper/host_globals.h"
+#include "content/renderer/pepper/npapi_glue.h"
+#include "content/renderer/pepper/npobject_var.h"
+#include "content/renderer/pepper/plugin_module.h"
+#include "content/renderer/pepper/plugin_object.h"
+#include "content/renderer/pepper/ppapi_plugin_instance_impl.h"
+#include "ppapi/c/dev/ppb_var_deprecated.h"
+#include "ppapi/c/ppb_var.h"
+#include "ppapi/c/pp_var.h"
+#include "ppapi/shared_impl/ppb_var_shared.h"
+#include "third_party/WebKit/public/web/WebBindings.h"
+#include "third_party/WebKit/public/web/WebScopedUserGesture.h"
+
+using ppapi::NPObjectVar;
+using ppapi::PpapiGlobals;
+using ppapi::StringVar;
+using ppapi::Var;
+using WebKit::WebBindings;
+
+namespace webkit {
+namespace ppapi {
+
+namespace {
+
+const char kInvalidObjectException[] = "Error: Invalid object";
+const char kInvalidPropertyException[] = "Error: Invalid property";
+const char kInvalidValueException[] = "Error: Invalid value";
+const char kUnableToGetPropertyException[] = "Error: Unable to get property";
+const char kUnableToSetPropertyException[] = "Error: Unable to set property";
+const char kUnableToRemovePropertyException[] =
+    "Error: Unable to remove property";
+const char kUnableToGetAllPropertiesException[] =
+    "Error: Unable to get all properties";
+const char kUnableToCallMethodException[] = "Error: Unable to call method";
+const char kUnableToConstructException[] = "Error: Unable to construct";
+
+// ---------------------------------------------------------------------------
+// Utilities
+
+// Converts the given PP_Var to an NPVariant, returning true on success.
+// False means that the given variant is invalid. In this case, the result
+// NPVariant will be set to a void one.
+//
+// The contents of the PP_Var will NOT be copied, so you need to ensure that
+// the PP_Var remains valid while the resultant NPVariant is in use.
+bool PPVarToNPVariantNoCopy(PP_Var var, NPVariant* result) {
+  switch (var.type) {
+    case PP_VARTYPE_UNDEFINED:
+      VOID_TO_NPVARIANT(*result);
+      break;
+    case PP_VARTYPE_NULL:
+      NULL_TO_NPVARIANT(*result);
+      break;
+    case PP_VARTYPE_BOOL:
+      BOOLEAN_TO_NPVARIANT(var.value.as_bool, *result);
+      break;
+    case PP_VARTYPE_INT32:
+      INT32_TO_NPVARIANT(var.value.as_int, *result);
+      break;
+    case PP_VARTYPE_DOUBLE:
+      DOUBLE_TO_NPVARIANT(var.value.as_double, *result);
+      break;
+    case PP_VARTYPE_STRING: {
+      StringVar* string = StringVar::FromPPVar(var);
+      if (!string) {
+        VOID_TO_NPVARIANT(*result);
+        return false;
+      }
+      const std::string& value = string->value();
+      STRINGN_TO_NPVARIANT(value.c_str(), value.size(), *result);
+      break;
+    }
+    case PP_VARTYPE_OBJECT: {
+      scoped_refptr<NPObjectVar> object(NPObjectVar::FromPPVar(var));
+      if (!object.get()) {
+        VOID_TO_NPVARIANT(*result);
+        return false;
+      }
+      OBJECT_TO_NPVARIANT(object->np_object(), *result);
+      break;
+    }
+    default:
+      VOID_TO_NPVARIANT(*result);
+      return false;
+  }
+  return true;
+}
+
+// ObjectAccessorTryCatch ------------------------------------------------------
+
+// Automatically sets up a TryCatch for accessing the object identified by the
+// given PP_Var. The module from the object will be used for the exception
+// strings generated by the TryCatch.
+//
+// This will automatically retrieve the ObjectVar from the object and throw
+// an exception if it's invalid. At the end of construction, if there is no
+// exception, you know that there is no previously set exception, that the
+// object passed in is valid and ready to use (via the object() getter), and
+// that the TryCatch's pp_module() getter is also set up properly and ready to
+// use.
+class ObjectAccessorTryCatch : public TryCatch {
+ public:
+  ObjectAccessorTryCatch(PP_Var object, PP_Var* exception)
+      : TryCatch(exception),
+        object_(NPObjectVar::FromPPVar(object)) {
+    if (!object_.get()) {
+      SetException(kInvalidObjectException);
+    }
+  }
+
+  NPObjectVar* object() { return object_.get(); }
+
+  PluginInstanceImpl* GetPluginInstance() {
+    return HostGlobals::Get()->GetInstance(object()->pp_instance());
+  }
+
+ protected:
+  scoped_refptr<NPObjectVar> object_;
+
+  DISALLOW_COPY_AND_ASSIGN(ObjectAccessorTryCatch);
+};
+
+// ObjectAccessiorWithIdentifierTryCatch ---------------------------------------
+
+// Automatically sets up a TryCatch for accessing the identifier on the given
+// object. This just extends ObjectAccessorTryCatch to additionally convert
+// the given identifier to an NPIdentifier and validate it, throwing an
+// exception if it's invalid.
+//
+// At the end of construction, if there is no exception, you know that there is
+// no previously set exception, that the object passed in is valid and ready to
+// use (via the object() getter), that the identifier is valid and ready to
+// use (via the identifier() getter), and that the TryCatch's pp_module() getter
+// is also set up properly and ready to use.
+class ObjectAccessorWithIdentifierTryCatch : public ObjectAccessorTryCatch {
+ public:
+  ObjectAccessorWithIdentifierTryCatch(PP_Var object,
+                                       PP_Var identifier,
+                                       PP_Var* exception)
+      : ObjectAccessorTryCatch(object, exception),
+        identifier_(0) {
+    if (!has_exception()) {
+      identifier_ = PPVarToNPIdentifier(identifier);
+      if (!identifier_)
+        SetException(kInvalidPropertyException);
+    }
+  }
+
+  NPIdentifier identifier() const { return identifier_; }
+
+ private:
+  NPIdentifier identifier_;
+
+  DISALLOW_COPY_AND_ASSIGN(ObjectAccessorWithIdentifierTryCatch);
+};
+
+PP_Bool HasProperty(PP_Var var,
+                    PP_Var name,
+                    PP_Var* exception) {
+  ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
+  if (accessor.has_exception())
+    return PP_FALSE;
+  return BoolToPPBool(WebBindings::hasProperty(NULL,
+                                               accessor.object()->np_object(),
+                                               accessor.identifier()));
+}
+
+bool HasPropertyDeprecated(PP_Var var,
+                           PP_Var name,
+                           PP_Var* exception) {
+  return PPBoolToBool(HasProperty(var, name, exception));
+}
+
+bool HasMethodDeprecated(PP_Var var,
+                         PP_Var name,
+                         PP_Var* exception) {
+  ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
+  if (accessor.has_exception())
+    return false;
+  return WebBindings::hasMethod(NULL, accessor.object()->np_object(),
+                                accessor.identifier());
+}
+
+PP_Var GetProperty(PP_Var var,
+                   PP_Var name,
+                   PP_Var* exception) {
+  ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
+  if (accessor.has_exception())
+    return PP_MakeUndefined();
+
+  NPVariant result;
+  if (!WebBindings::getProperty(NULL, accessor.object()->np_object(),
+                                accessor.identifier(), &result)) {
+    // An exception may have been raised.
+    accessor.SetException(kUnableToGetPropertyException);
+    return PP_MakeUndefined();
+  }
+
+  PP_Var ret = NPVariantToPPVar(accessor.GetPluginInstance(), &result);
+  WebBindings::releaseVariantValue(&result);
+  return ret;
+}
+
+void EnumerateProperties(PP_Var var,
+                         uint32_t* property_count,
+                         PP_Var** properties,
+                         PP_Var* exception) {
+  *properties = NULL;
+  *property_count = 0;
+
+  ObjectAccessorTryCatch accessor(var, exception);
+  if (accessor.has_exception())
+    return;
+
+  NPIdentifier* identifiers = NULL;
+  uint32_t count = 0;
+  if (!WebBindings::enumerate(NULL, accessor.object()->np_object(),
+                              &identifiers, &count)) {
+    accessor.SetException(kUnableToGetAllPropertiesException);
+    return;
+  }
+
+  if (count == 0)
+    return;
+
+  *property_count = count;
+  *properties = static_cast<PP_Var*>(malloc(sizeof(PP_Var) * count));
+  for (uint32_t i = 0; i < count; ++i) {
+    (*properties)[i] = NPIdentifierToPPVar(identifiers[i]);
+  }
+  free(identifiers);
+}
+
+void SetPropertyDeprecated(PP_Var var,
+                           PP_Var name,
+                           PP_Var value,
+                           PP_Var* exception) {
+  ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
+  if (accessor.has_exception())
+    return;
+
+  NPVariant variant;
+  if (!PPVarToNPVariantNoCopy(value, &variant)) {
+    accessor.SetException(kInvalidValueException);
+    return;
+  }
+  if (!WebBindings::setProperty(NULL, accessor.object()->np_object(),
+                                accessor.identifier(), &variant))
+    accessor.SetException(kUnableToSetPropertyException);
+}
+
+void DeletePropertyDeprecated(PP_Var var,
+                              PP_Var name,
+                              PP_Var* exception) {
+  ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
+  if (accessor.has_exception())
+    return;
+
+  if (!WebBindings::removeProperty(NULL, accessor.object()->np_object(),
+                                   accessor.identifier()))
+    accessor.SetException(kUnableToRemovePropertyException);
+}
+
+PP_Var InternalCallDeprecated(ObjectAccessorTryCatch* accessor,
+                              PP_Var method_name,
+                              uint32_t argc,
+                              PP_Var* argv,
+                              PP_Var* exception) {
+  NPIdentifier identifier;
+  if (method_name.type == PP_VARTYPE_UNDEFINED) {
+    identifier = NULL;
+  } else if (method_name.type == PP_VARTYPE_STRING) {
+    // Specifically allow only string functions to be called.
+    identifier = PPVarToNPIdentifier(method_name);
+    if (!identifier) {
+      accessor->SetException(kInvalidPropertyException);
+      return PP_MakeUndefined();
+    }
+  } else {
+    accessor->SetException(kInvalidPropertyException);
+    return PP_MakeUndefined();
+  }
+
+  scoped_ptr<NPVariant[]> args;
+  if (argc) {
+    args.reset(new NPVariant[argc]);
+    for (uint32_t i = 0; i < argc; ++i) {
+      if (!PPVarToNPVariantNoCopy(argv[i], &args[i])) {
+        // This argument was invalid, throw an exception & give up.
+        accessor->SetException(kInvalidValueException);
+        return PP_MakeUndefined();
+      }
+    }
+  }
+
+  bool ok;
+
+  NPVariant result;
+  if (identifier) {
+    ok = WebBindings::invoke(NULL, accessor->object()->np_object(),
+                             identifier, args.get(), argc, &result);
+  } else {
+    ok = WebBindings::invokeDefault(NULL, accessor->object()->np_object(),
+                                    args.get(), argc, &result);
+  }
+
+  if (!ok) {
+    // An exception may have been raised.
+    accessor->SetException(kUnableToCallMethodException);
+    return PP_MakeUndefined();
+  }
+
+  PP_Var ret = NPVariantToPPVar(accessor->GetPluginInstance(), &result);
+  WebBindings::releaseVariantValue(&result);
+  return ret;
+}
+
+PP_Var CallDeprecated(PP_Var var,
+                      PP_Var method_name,
+                      uint32_t argc,
+                      PP_Var* argv,
+                      PP_Var* exception) {
+  ObjectAccessorTryCatch accessor(var, exception);
+  if (accessor.has_exception())
+    return PP_MakeUndefined();
+  PluginInstanceImpl* plugin = accessor.GetPluginInstance();
+  if (plugin && plugin->IsProcessingUserGesture()) {
+    WebKit::WebScopedUserGesture user_gesture(
+        plugin->CurrentUserGestureToken());
+    return InternalCallDeprecated(&accessor, method_name, argc, argv,
+                                  exception);
+  }
+  return InternalCallDeprecated(&accessor, method_name, argc, argv, exception);
+}
+
+PP_Var Construct(PP_Var var,
+                 uint32_t argc,
+                 PP_Var* argv,
+                 PP_Var* exception) {
+  ObjectAccessorTryCatch accessor(var, exception);
+  if (accessor.has_exception())
+    return PP_MakeUndefined();
+
+  scoped_ptr<NPVariant[]> args;
+  if (argc) {
+    args.reset(new NPVariant[argc]);
+    for (uint32_t i = 0; i < argc; ++i) {
+      if (!PPVarToNPVariantNoCopy(argv[i], &args[i])) {
+        // This argument was invalid, throw an exception & give up.
+        accessor.SetException(kInvalidValueException);
+        return PP_MakeUndefined();
+      }
+    }
+  }
+
+  NPVariant result;
+  if (!WebBindings::construct(NULL, accessor.object()->np_object(),
+                              args.get(), argc, &result)) {
+    // An exception may have been raised.
+    accessor.SetException(kUnableToConstructException);
+    return PP_MakeUndefined();
+  }
+
+  PP_Var ret = NPVariantToPPVar(accessor.GetPluginInstance(), &result);
+  WebBindings::releaseVariantValue(&result);
+  return ret;
+}
+
+bool IsInstanceOfDeprecated(PP_Var var,
+                            const PPP_Class_Deprecated* ppp_class,
+                            void** ppp_class_data) {
+  scoped_refptr<NPObjectVar> object(NPObjectVar::FromPPVar(var));
+  if (!object.get())
+    return false;  // Not an object at all.
+
+  return PluginObject::IsInstanceOf(object->np_object(),
+                                    ppp_class, ppp_class_data);
+}
+
+PP_Var CreateObjectDeprecated(PP_Instance pp_instance,
+                              const PPP_Class_Deprecated* ppp_class,
+                              void* ppp_class_data) {
+  PluginInstanceImpl* instance = HostGlobals::Get()->GetInstance(pp_instance);
+  if (!instance) {
+    DLOG(ERROR) << "Create object passed an invalid instance.";
+    return PP_MakeNull();
+  }
+  return PluginObject::Create(instance, ppp_class, ppp_class_data);
+}
+
+PP_Var CreateObjectWithModuleDeprecated(PP_Module pp_module,
+                                        const PPP_Class_Deprecated* ppp_class,
+                                        void* ppp_class_data) {
+  PluginModule* module = HostGlobals::Get()->GetModule(pp_module);
+  if (!module)
+    return PP_MakeNull();
+  return PluginObject::Create(module->GetSomeInstance(),
+                              ppp_class, ppp_class_data);
+}
+
+}  // namespace
+
+// static
+const PPB_Var_Deprecated* PPB_Var_Deprecated_Impl::GetVarDeprecatedInterface() {
+  static const PPB_Var_Deprecated var_deprecated_interface = {
+    ::ppapi::PPB_Var_Shared::GetVarInterface1_0()->AddRef,
+    ::ppapi::PPB_Var_Shared::GetVarInterface1_0()->Release,
+    ::ppapi::PPB_Var_Shared::GetVarInterface1_0()->VarFromUtf8,
+    ::ppapi::PPB_Var_Shared::GetVarInterface1_0()->VarToUtf8,
+    &HasPropertyDeprecated,
+    &HasMethodDeprecated,
+    &GetProperty,
+    &EnumerateProperties,
+    &SetPropertyDeprecated,
+    &DeletePropertyDeprecated,
+    &CallDeprecated,
+    &Construct,
+    &IsInstanceOfDeprecated,
+    &CreateObjectDeprecated,
+    &CreateObjectWithModuleDeprecated,
+  };
+
+  return &var_deprecated_interface;
+}
+
+}  // namespace ppapi
+}  // namespace webkit
+