summaryrefslogtreecommitdiffstats
path: root/gpu/np_utils
diff options
context:
space:
mode:
Diffstat (limited to 'gpu/np_utils')
-rw-r--r--gpu/np_utils/default_np_object.h84
-rw-r--r--gpu/np_utils/dispatched_np_object_unittest.cc403
-rw-r--r--gpu/np_utils/dynamic_np_object.cc59
-rw-r--r--gpu/np_utils/dynamic_np_object.h35
-rw-r--r--gpu/np_utils/dynamic_np_object_unittest.cc83
-rw-r--r--gpu/np_utils/np_browser.cc123
-rw-r--r--gpu/np_utils/np_browser.h95
-rw-r--r--gpu/np_utils/np_browser_mock.h50
-rw-r--r--gpu/np_utils/np_browser_stub.cc125
-rw-r--r--gpu/np_utils/np_browser_stub.h84
-rw-r--r--gpu/np_utils/np_class.h125
-rw-r--r--gpu/np_utils/np_class_unittest.cc143
-rw-r--r--gpu/np_utils/np_dispatcher.cc86
-rw-r--r--gpu/np_utils/np_dispatcher.h224
-rw-r--r--gpu/np_utils/np_dispatcher_specializations.h85
-rw-r--r--gpu/np_utils/np_headers.h11
-rw-r--r--gpu/np_utils/np_object_mock.h36
-rw-r--r--gpu/np_utils/np_object_pointer.h119
-rw-r--r--gpu/np_utils/np_object_pointer_unittest.cc220
-rw-r--r--gpu/np_utils/np_plugin_object.h50
-rw-r--r--gpu/np_utils/np_plugin_object_factory.cc30
-rw-r--r--gpu/np_utils/np_plugin_object_factory.h37
-rw-r--r--gpu/np_utils/np_plugin_object_factory_mock.h23
-rw-r--r--gpu/np_utils/np_plugin_object_mock.h26
-rw-r--r--gpu/np_utils/np_utils.cc170
-rw-r--r--gpu/np_utils/np_utils.h271
-rw-r--r--gpu/np_utils/np_utils_unittest.cc424
-rw-r--r--gpu/np_utils/webkit_browser.h117
28 files changed, 3338 insertions, 0 deletions
diff --git a/gpu/np_utils/default_np_object.h b/gpu/np_utils/default_np_object.h
new file mode 100644
index 0000000..b3b5fc0
--- /dev/null
+++ b/gpu/np_utils/default_np_object.h
@@ -0,0 +1,84 @@
+// Copyright (c) 2006-2008 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.
+
+#ifndef GPU_NP_UTILS_DEFAULT_NP_OBJECT_H_
+#define GPU_NP_UTILS_DEFAULT_NP_OBJECT_H_
+
+#include "base/basictypes.h"
+#include "gpu/np_utils/np_headers.h"
+
+namespace np_utils {
+
+class BaseNPDispatcher;
+
+// This class implements each of the functions in the NPClass interface. They
+// all return error by default. Note that these are not virtual functions and
+// this is not an interface. This class can be used as a mixin so that an
+// NPObject class does not need to implement every NPClass function but rather
+// inherits a default from DefaultNPObject.
+template <typename RootClass>
+class DefaultNPObject : public RootClass {
+ public:
+ void Invalidate() {}
+
+ bool HasMethod(NPIdentifier name) {
+ return false;
+ }
+
+ bool Invoke(NPIdentifier name,
+ const NPVariant* args,
+ uint32_t num_args,
+ NPVariant* result) {
+ return false;
+ }
+
+ bool InvokeDefault(const NPVariant* args,
+ uint32_t num_args,
+ NPVariant* result) {
+ return false;
+ }
+
+ bool HasProperty(NPIdentifier name) {
+ return false;
+ }
+
+ bool GetProperty(NPIdentifier name, NPVariant* result) {
+ return false;
+ }
+
+ bool SetProperty(NPIdentifier name, const NPVariant* value) {
+ return false;
+ }
+
+ bool RemoveProperty(NPIdentifier name) {
+ return false;
+ }
+
+ bool Enumerate(NPIdentifier** names,
+ uint32_t* count) {
+ *names = NULL;
+ *count = 0;
+ return true;
+ }
+
+ bool Construct(const NPVariant* args,
+ uint32_t num_args,
+ NPVariant* result) {
+ return false;
+ }
+
+ static BaseNPDispatcher* GetDispatcherChain() {
+ return NULL;
+ }
+
+ protected:
+ DefaultNPObject() {}
+ virtual ~DefaultNPObject() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(DefaultNPObject);
+};
+} // namespace np_utils
+
+#endif // GPU_NP_UTILS_DEFAULT_NP_OBJECT_H_
diff --git a/gpu/np_utils/dispatched_np_object_unittest.cc b/gpu/np_utils/dispatched_np_object_unittest.cc
new file mode 100644
index 0000000..19d5a2b
--- /dev/null
+++ b/gpu/np_utils/dispatched_np_object_unittest.cc
@@ -0,0 +1,403 @@
+// Copyright (c) 2006-2008 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 <string>
+
+#include "gpu/np_utils/default_np_object.h"
+#include "gpu/np_utils/np_browser_stub.h"
+#include "gpu/np_utils/np_dispatcher.h"
+#include "gpu/np_utils/np_object_mock.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::Return;
+using testing::StrictMock;
+
+namespace np_utils {
+
+// This mock class has a dispatcher chain with an entry for each mocked
+// function. The tests that follow that invoking an NPAPI method calls the
+// corresponding mocked member function.
+class MockDispatchedNPObject : public DefaultNPObject<NPObject> {
+ public:
+ explicit MockDispatchedNPObject(NPP npp) {
+ }
+
+ MOCK_METHOD0(VoidReturnNoParams, void());
+ MOCK_METHOD1(VoidReturnBoolParam, void(bool));
+ MOCK_METHOD1(VoidReturnIntParam, void(int));
+ MOCK_METHOD1(VoidReturnFloatParam, void(float));
+ MOCK_METHOD1(VoidReturnDoubleParam, void(double));
+ MOCK_METHOD1(VoidReturnStringParam, void(std::string));
+ MOCK_METHOD1(VoidReturnObjectParam, void(NPObjectPointer<NPObject>));
+ MOCK_METHOD2(VoidReturnTwoParams, void(bool, int));
+ MOCK_METHOD0(Overloaded, void());
+ MOCK_METHOD1(Overloaded, void(bool));
+ MOCK_METHOD1(Overloaded, void(std::string));
+ MOCK_METHOD0(BoolReturn, bool());
+ MOCK_METHOD0(IntReturn, int());
+ MOCK_METHOD0(FloatReturn, float());
+ MOCK_METHOD0(DoubleReturn, double());
+ MOCK_METHOD0(StringReturn, std::string());
+ MOCK_METHOD0(ObjectReturn, NPObjectPointer<NPObject>());
+
+ NP_UTILS_BEGIN_DISPATCHER_CHAIN(MockDispatchedNPObject, DefaultNPObject<NPObject>)
+ NP_UTILS_DISPATCHER(VoidReturnNoParams, void())
+ NP_UTILS_DISPATCHER(VoidReturnBoolParam, void(bool))
+ NP_UTILS_DISPATCHER(VoidReturnIntParam, void(int))
+ NP_UTILS_DISPATCHER(VoidReturnFloatParam, void(float))
+ NP_UTILS_DISPATCHER(VoidReturnDoubleParam, void(double))
+ NP_UTILS_DISPATCHER(VoidReturnStringParam, void(std::string))
+ NP_UTILS_DISPATCHER(VoidReturnObjectParam, void(NPObjectPointer<NPObject>))
+ NP_UTILS_DISPATCHER(VoidReturnTwoParams, void(bool, int))
+ NP_UTILS_DISPATCHER(Overloaded, void())
+ NP_UTILS_DISPATCHER(Overloaded, void(bool))
+ NP_UTILS_DISPATCHER(Overloaded, void(std::string))
+ NP_UTILS_DISPATCHER(BoolReturn, bool())
+ NP_UTILS_DISPATCHER(IntReturn, int())
+ NP_UTILS_DISPATCHER(FloatReturn, float())
+ NP_UTILS_DISPATCHER(DoubleReturn, double())
+ NP_UTILS_DISPATCHER(StringReturn, std::string())
+ NP_UTILS_DISPATCHER(ObjectReturn, NPObjectPointer<NPObject>());
+ NP_UTILS_END_DISPATCHER_CHAIN
+};
+
+class DispatchedNPObjectTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ object_ = NPCreateObject<StrictMock<MockDispatchedNPObject> >(NULL);
+ passed_object_ = NPCreateObject<MockNPObject>(NULL);
+
+ for (int i = 0; i != arraysize(args_); ++i) {
+ NULL_TO_NPVARIANT(args_[i]);
+ }
+ NULL_TO_NPVARIANT(result_);
+ }
+
+ StubNPBrowser stub_browser_;
+ NPVariant args_[3];
+ NPVariant result_;
+ NPObjectPointer<MockDispatchedNPObject> object_;
+ NPObjectPointer<NPObject> passed_object_;
+};
+
+TEST_F(DispatchedNPObjectTest, CannotInvokeMissingFunction) {
+ EXPECT_FALSE(object_->Invoke(
+ NPBrowser::get()->GetStringIdentifier("missing"),
+ NULL,
+ 0,
+ &result_));
+ EXPECT_TRUE(NPVARIANT_IS_VOID(result_));
+}
+
+TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnNoParams) {
+ EXPECT_CALL(*object_, VoidReturnNoParams());
+
+ EXPECT_TRUE(object_->Invoke(
+ NPBrowser::get()->GetStringIdentifier("voidReturnNoParams"),
+ NULL,
+ 0,
+ &result_));
+ EXPECT_TRUE(NPVARIANT_IS_VOID(result_));
+}
+
+TEST_F(DispatchedNPObjectTest,
+ CannotInvokeVoidReturnNoParamsWithTooManyParams) {
+ EXPECT_FALSE(object_->Invoke(
+ NPBrowser::get()->GetStringIdentifier("voidReturnNoParams"),
+ args_,
+ 1,
+ &result_));
+ EXPECT_TRUE(NPVARIANT_IS_VOID(result_));
+}
+
+TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnIntParam) {
+ EXPECT_CALL(*object_, VoidReturnIntParam(7));
+
+ INT32_TO_NPVARIANT(7, args_[0]);
+
+ EXPECT_TRUE(object_->Invoke(
+ NPBrowser::get()->GetStringIdentifier("voidReturnIntParam"),
+ args_,
+ 1,
+ &result_));
+ EXPECT_TRUE(NPVARIANT_IS_VOID(result_));
+}
+
+TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnBoolParam) {
+ EXPECT_CALL(*object_, VoidReturnBoolParam(true));
+
+ BOOLEAN_TO_NPVARIANT(true, args_[0]);
+
+ EXPECT_TRUE(object_->Invoke(
+ NPBrowser::get()->GetStringIdentifier("voidReturnBoolParam"),
+ args_,
+ 1,
+ &result_));
+ EXPECT_TRUE(NPVARIANT_IS_VOID(result_));
+}
+
+TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnFloatParamWithDoubleParam) {
+ EXPECT_CALL(*object_, VoidReturnFloatParam(7.0f));
+
+ DOUBLE_TO_NPVARIANT(7.0, args_[0]);
+
+ EXPECT_TRUE(object_->Invoke(
+ NPBrowser::get()->GetStringIdentifier("voidReturnFloatParam"),
+ args_,
+ 1,
+ &result_));
+ EXPECT_TRUE(NPVARIANT_IS_VOID(result_));
+}
+
+TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnFloatParamWithIntParam) {
+ EXPECT_CALL(*object_, VoidReturnFloatParam(7.0f));
+
+ INT32_TO_NPVARIANT(7, args_[0]);
+
+ EXPECT_TRUE(object_->Invoke(
+ NPBrowser::get()->GetStringIdentifier("voidReturnFloatParam"),
+ args_,
+ 1,
+ &result_));
+ EXPECT_TRUE(NPVARIANT_IS_VOID(result_));
+}
+
+TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnDoubleParamWithDoubleParam) {
+ EXPECT_CALL(*object_, VoidReturnDoubleParam(7.0));
+
+ DOUBLE_TO_NPVARIANT(7.0, args_[0]);
+
+ EXPECT_TRUE(object_->Invoke(
+ NPBrowser::get()->GetStringIdentifier("voidReturnDoubleParam"),
+ args_,
+ 1,
+ &result_));
+ EXPECT_TRUE(NPVARIANT_IS_VOID(result_));
+}
+
+TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnDoubleParamWithIntParam) {
+ EXPECT_CALL(*object_, VoidReturnDoubleParam(7.0f));
+
+ INT32_TO_NPVARIANT(7, args_[0]);
+
+ EXPECT_TRUE(object_->Invoke(
+ NPBrowser::get()->GetStringIdentifier("voidReturnDoubleParam"),
+ args_,
+ 1,
+ &result_));
+ EXPECT_TRUE(NPVARIANT_IS_VOID(result_));
+}
+
+TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnStringParam) {
+ EXPECT_CALL(*object_, VoidReturnStringParam(std::string("hello")));
+
+ STRINGZ_TO_NPVARIANT("hello", args_[0]);
+
+ EXPECT_TRUE(object_->Invoke(
+ NPBrowser::get()->GetStringIdentifier("voidReturnStringParam"),
+ args_,
+ 1,
+ &result_));
+ EXPECT_TRUE(NPVARIANT_IS_VOID(result_));
+}
+
+TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnObjectParamWithObject) {
+ EXPECT_CALL(*object_, VoidReturnObjectParam(passed_object_));
+
+ OBJECT_TO_NPVARIANT(passed_object_.Get(), args_[0]);
+
+ EXPECT_TRUE(object_->Invoke(
+ NPBrowser::get()->GetStringIdentifier("voidReturnObjectParam"),
+ args_,
+ 1,
+ &result_));
+ EXPECT_TRUE(NPVARIANT_IS_VOID(result_));
+}
+
+TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnObjectParamWithNull) {
+ EXPECT_CALL(
+ *object_,
+ VoidReturnObjectParam(NPObjectPointer<NPObject>()));
+
+ NULL_TO_NPVARIANT(args_[0]);
+
+ EXPECT_TRUE(object_->Invoke(
+ NPBrowser::get()->GetStringIdentifier("voidReturnObjectParam"),
+ args_,
+ 1,
+ &result_));
+ EXPECT_TRUE(NPVARIANT_IS_VOID(result_));
+}
+
+TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnTwoParams) {
+ EXPECT_CALL(*object_, VoidReturnTwoParams(false, 7));
+
+ BOOLEAN_TO_NPVARIANT(false, args_[0]);
+ INT32_TO_NPVARIANT(7, args_[1]);
+
+ EXPECT_TRUE(object_->Invoke(
+ NPBrowser::get()->GetStringIdentifier("voidReturnTwoParams"),
+ args_,
+ 2,
+ &result_));
+ EXPECT_TRUE(NPVARIANT_IS_VOID(result_));
+}
+
+TEST_F(DispatchedNPObjectTest, CanInvokeOverloadedWithNoParams) {
+ EXPECT_CALL(*object_, Overloaded());
+
+ EXPECT_TRUE(object_->Invoke(
+ NPBrowser::get()->GetStringIdentifier("overloaded"),
+ NULL,
+ 0,
+ &result_));
+ EXPECT_TRUE(NPVARIANT_IS_VOID(result_));
+}
+
+TEST_F(DispatchedNPObjectTest, CanInvokeOverloadedWithOneStringParam) {
+ EXPECT_CALL(*object_, Overloaded(std::string("hello")));
+
+ STRINGZ_TO_NPVARIANT("hello", args_[0]);
+
+ EXPECT_TRUE(object_->Invoke(
+ NPBrowser::get()->GetStringIdentifier("overloaded"),
+ args_,
+ 1,
+ &result_));
+ EXPECT_TRUE(NPVARIANT_IS_VOID(result_));
+}
+
+TEST_F(DispatchedNPObjectTest, CanInvokeOverloadedWithOneBoolParam) {
+ EXPECT_CALL(*object_, Overloaded(true));
+
+ BOOLEAN_TO_NPVARIANT(true, args_[0]);
+
+ EXPECT_TRUE(object_->Invoke(
+ NPBrowser::get()->GetStringIdentifier("overloaded"),
+ args_,
+ 1,
+ &result_));
+ EXPECT_TRUE(NPVARIANT_IS_VOID(result_));
+}
+
+TEST_F(DispatchedNPObjectTest, CanInvokeBoolReturn) {
+ EXPECT_CALL(*object_, BoolReturn()).WillOnce(Return(true));
+
+ EXPECT_TRUE(object_->Invoke(
+ NPBrowser::get()->GetStringIdentifier("boolReturn"),
+ NULL,
+ 0,
+ &result_));
+ EXPECT_TRUE(NPVARIANT_IS_BOOLEAN(result_));
+ EXPECT_TRUE(NPVARIANT_TO_BOOLEAN(result_));
+}
+
+TEST_F(DispatchedNPObjectTest, CanInvokeIntReturn) {
+ EXPECT_CALL(*object_, IntReturn()).WillOnce(Return(7));
+
+ EXPECT_TRUE(object_->Invoke(
+ NPBrowser::get()->GetStringIdentifier("intReturn"),
+ NULL,
+ 0,
+ &result_));
+ EXPECT_TRUE(NPVARIANT_IS_INT32(result_));
+ EXPECT_EQ(7, NPVARIANT_TO_INT32(result_));
+}
+
+TEST_F(DispatchedNPObjectTest, CanInvokeFloatReturn) {
+ EXPECT_CALL(*object_, FloatReturn()).WillOnce(Return(7.0f));
+
+ EXPECT_TRUE(object_->Invoke(
+ NPBrowser::get()->GetStringIdentifier("floatReturn"),
+ NULL,
+ 0,
+ &result_));
+ EXPECT_TRUE(NPVARIANT_IS_DOUBLE(result_));
+ EXPECT_EQ(7.0, NPVARIANT_TO_DOUBLE(result_));
+}
+
+TEST_F(DispatchedNPObjectTest, CanInvokeDoubleReturn) {
+ EXPECT_CALL(*object_, DoubleReturn()).WillOnce(Return(7.0));
+
+ EXPECT_TRUE(object_->Invoke(
+ NPBrowser::get()->GetStringIdentifier("doubleReturn"),
+ NULL,
+ 0,
+ &result_));
+ EXPECT_TRUE(NPVARIANT_IS_DOUBLE(result_));
+ EXPECT_EQ(7.0, NPVARIANT_TO_DOUBLE(result_));
+}
+
+TEST_F(DispatchedNPObjectTest, CanInvokeStringReturn) {
+ EXPECT_CALL(*object_, StringReturn()).WillOnce(Return(std::string("hello")));
+
+ EXPECT_TRUE(object_->Invoke(
+ NPBrowser::get()->GetStringIdentifier("stringReturn"),
+ NULL,
+ 0,
+ &result_));
+ EXPECT_TRUE(NPVARIANT_IS_STRING(result_));
+
+ NPString& str = NPVARIANT_TO_STRING(result_);
+ EXPECT_EQ(std::string("hello"),
+ std::string(str.UTF8Characters, str.UTF8Length));
+
+ // Callee is responsible for releasing string.
+ NPBrowser::get()->ReleaseVariantValue(&result_);
+}
+
+TEST_F(DispatchedNPObjectTest, CanInvokeObjectReturnWithObject) {
+ EXPECT_CALL(*object_, ObjectReturn()).WillOnce(Return(passed_object_));
+
+ EXPECT_TRUE(object_->Invoke(
+ NPBrowser::get()->GetStringIdentifier("objectReturn"),
+ NULL,
+ 0,
+ &result_));
+ EXPECT_TRUE(NPVARIANT_IS_OBJECT(result_));
+ EXPECT_EQ(passed_object_.Get(), NPVARIANT_TO_OBJECT(result_));
+
+ NPBrowser::get()->ReleaseVariantValue(&result_);
+}
+
+TEST_F(DispatchedNPObjectTest, CanInvokeObjectReturnWithNull) {
+ EXPECT_CALL(*object_, ObjectReturn())
+ .WillOnce(Return(NPObjectPointer<NPObject>()));
+
+ EXPECT_TRUE(object_->Invoke(
+ NPBrowser::get()->GetStringIdentifier("objectReturn"),
+ NULL,
+ 0,
+ &result_));
+ EXPECT_TRUE(NPVARIANT_IS_NULL(result_));
+}
+
+TEST_F(DispatchedNPObjectTest, HasMethodReturnsTrueIfMatchingMemberVariable) {
+ EXPECT_TRUE(object_->HasMethod(
+ NPBrowser::get()->GetStringIdentifier("objectReturn")));
+}
+
+TEST_F(DispatchedNPObjectTest, HasMethodReturnsTrueIfNoMatchingMemberVariable) {
+ EXPECT_FALSE(object_->HasMethod(
+ NPBrowser::get()->GetStringIdentifier("missing")));
+}
+
+TEST_F(DispatchedNPObjectTest, EnumeratesAllAvailableMethods) {
+ NPIdentifier* names;
+ uint32_t num_names;
+ ASSERT_TRUE(object_->Enumerate(&names, &num_names));
+
+ // Don't compare all of them; this test would need to change every time new
+ // dispatchers were added to the test NPObject class. Just compare the first
+ // registered (last in the dispatcher chain) and that more than one is
+ // returned.
+ EXPECT_GT(num_names, 1u);
+ EXPECT_EQ(NPBrowser::get()->GetStringIdentifier("voidReturnNoParams"),
+ names[num_names - 1]);
+
+ NPBrowser::get()->MemFree(names);
+}
+
+} // namespace np_utils
diff --git a/gpu/np_utils/dynamic_np_object.cc b/gpu/np_utils/dynamic_np_object.cc
new file mode 100644
index 0000000..e037fdc
--- /dev/null
+++ b/gpu/np_utils/dynamic_np_object.cc
@@ -0,0 +1,59 @@
+// Copyright (c) 2006-2008 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 "gpu/np_utils/dynamic_np_object.h"
+
+namespace np_utils {
+
+DynamicNPObject::DynamicNPObject(NPP npp) {
+}
+
+void DynamicNPObject::Invalidate() {
+ for (PropertyMap::iterator it = properties_.begin();
+ it != properties_.end();
+ ++it) {
+ it->second.Invalidate();
+ }
+}
+
+bool DynamicNPObject::HasProperty(NPIdentifier name) {
+ PropertyMap::iterator it = properties_.find(name);
+ return it != properties_.end();
+}
+
+bool DynamicNPObject::GetProperty(NPIdentifier name, NPVariant* result) {
+ PropertyMap::iterator it = properties_.find(name);
+ if (it == properties_.end())
+ return false;
+
+ it->second.CopyTo(result);
+ return true;
+}
+
+bool DynamicNPObject::SetProperty(NPIdentifier name, const NPVariant* value) {
+ properties_[name] = *value;
+ return true;
+}
+
+bool DynamicNPObject::RemoveProperty(NPIdentifier name) {
+ properties_.erase(name);
+ return false;
+}
+
+bool DynamicNPObject::Enumerate(NPIdentifier** names, uint32_t* count) {
+ *names = static_cast<NPIdentifier*>(
+ NPBrowser::get()->MemAlloc(properties_.size() * sizeof(*names)));
+ *count = properties_.size();
+
+ int i = 0;
+ for (PropertyMap::iterator it = properties_.begin();
+ it != properties_.end();
+ ++it) {
+ (*names)[i] = it->first;
+ ++i;
+ }
+
+ return true;
+}
+} // namespace np_utils
diff --git a/gpu/np_utils/dynamic_np_object.h b/gpu/np_utils/dynamic_np_object.h
new file mode 100644
index 0000000..2b63e78
--- /dev/null
+++ b/gpu/np_utils/dynamic_np_object.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2006-2008 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.
+
+#ifndef GPU_NP_UTILS_DYNAMIC_NP_OBJECT_H_
+#define GPU_NP_UTILS_DYNAMIC_NP_OBJECT_H_
+
+#include <map>
+
+#include "gpu/np_utils/default_np_object.h"
+#include "gpu/np_utils/np_utils.h"
+
+namespace np_utils {
+
+// NPObjects of this type have a dictionary of property name / variant pairs
+// that can be changed at runtime through NPAPI.
+class DynamicNPObject : public DefaultNPObject<NPObject> {
+ public:
+ explicit DynamicNPObject(NPP npp);
+
+ void Invalidate();
+ bool HasProperty(NPIdentifier name);
+ bool GetProperty(NPIdentifier name, NPVariant* result);
+ bool SetProperty(NPIdentifier name, const NPVariant* value);
+ bool RemoveProperty(NPIdentifier name);
+ bool Enumerate(NPIdentifier** names, uint32_t* count);
+
+ private:
+ typedef std::map<NPIdentifier, SmartNPVariant> PropertyMap;
+ PropertyMap properties_;
+ DISALLOW_COPY_AND_ASSIGN(DynamicNPObject);
+};
+} // namespace np_utils
+
+#endif // GPU_NP_UTILS_DYNAMIC_NP_OBJECT_H_
diff --git a/gpu/np_utils/dynamic_np_object_unittest.cc b/gpu/np_utils/dynamic_np_object_unittest.cc
new file mode 100644
index 0000000..d58e963
--- /dev/null
+++ b/gpu/np_utils/dynamic_np_object_unittest.cc
@@ -0,0 +1,83 @@
+// Copyright (c) 2006-2008 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 <string>
+
+#include "gpu/np_utils/dynamic_np_object.h"
+#include "gpu/np_utils/np_browser_stub.h"
+#include "gpu/np_utils/np_utils.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::Return;
+using testing::StrictMock;
+
+namespace np_utils {
+
+class NPDynamicNPObjectTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ object_ = NPCreateObject<DynamicNPObject>(NULL);
+ }
+
+ StubNPBrowser stub_browser_;
+ NPObjectPointer<DynamicNPObject> object_;
+};
+
+TEST_F(NPDynamicNPObjectTest, HasPropertyReturnsFalseForMissingProperty) {
+ EXPECT_FALSE(NPHasProperty(NULL, object_, "missing"));
+}
+
+TEST_F(NPDynamicNPObjectTest, GetPropertyReturnsFalseForMissingProperty) {
+ int32 r;
+ EXPECT_FALSE(NPGetProperty(NULL, object_, "missing", &r));
+}
+
+TEST_F(NPDynamicNPObjectTest, CanSetProperty) {
+ EXPECT_TRUE(NPSetProperty(NULL, object_, "foo", 7));
+ int32 r;
+ EXPECT_TRUE(NPHasProperty(NULL, object_, "foo"));
+ EXPECT_TRUE(NPGetProperty(NULL, object_, "foo", &r));
+ EXPECT_EQ(7, r);
+}
+
+TEST_F(NPDynamicNPObjectTest, CanRemoveProperty) {
+ EXPECT_TRUE(NPSetProperty(NULL, object_, "foo", 7));
+ EXPECT_TRUE(NPHasProperty(NULL, object_, "foo"));
+ EXPECT_FALSE(NPRemoveProperty(NULL, object_, "foo"));
+ EXPECT_FALSE(NPHasProperty(NULL, object_, "foo"));
+ int32 r;
+ EXPECT_FALSE(NPGetProperty(NULL, object_, "foo", &r));
+}
+
+TEST_F(NPDynamicNPObjectTest, CanEnumerateProperties) {
+ EXPECT_TRUE(NPSetProperty(NULL, object_, "foo", 7));
+
+ NPIdentifier* names;
+ uint32 num_names;
+ EXPECT_TRUE(object_->_class->enumerate(object_.Get(), &names, &num_names));
+
+ EXPECT_EQ(1, num_names);
+ EXPECT_EQ(NPBrowser::get()->GetStringIdentifier("foo"), names[0]);
+
+ NPBrowser::get()->MemFree(names);
+}
+
+// Properties should not be
+TEST_F(NPDynamicNPObjectTest, InvalidateNullsObjectProperties) {
+ EXPECT_EQ(1, object_->referenceCount);
+ {
+ EXPECT_TRUE(NPSetProperty(NULL, object_, "foo", object_));
+ EXPECT_TRUE(NPHasProperty(NULL, object_, "foo"));
+ object_->_class->invalidate(object_.Get());
+ EXPECT_TRUE(NPHasProperty(NULL, object_, "foo"));
+ NPObjectPointer<DynamicNPObject> r;
+ EXPECT_TRUE(NPGetProperty(NULL, object_, "foo", &r));
+ EXPECT_TRUE(NULL == r.Get());
+ }
+ // Invalidate did not release object
+ EXPECT_EQ(2, object_->referenceCount);
+ NPBrowser::get()->ReleaseObject(object_.Get());
+}
+} // namespace np_utils
diff --git a/gpu/np_utils/np_browser.cc b/gpu/np_utils/np_browser.cc
new file mode 100644
index 0000000..d0d703c
--- /dev/null
+++ b/gpu/np_utils/np_browser.cc
@@ -0,0 +1,123 @@
+// Copyright (c) 2006-2008 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 "gpu/np_utils/np_browser.h"
+#include "base/logging.h"
+#include "webkit/glue/plugins/nphostapi.h"
+
+namespace np_utils {
+
+NPBrowser* NPBrowser::browser_;
+
+NPBrowser::NPBrowser(NPNetscapeFuncs* funcs)
+ : netscape_funcs_(funcs) {
+ // Make this the first browser in the linked list.
+ previous_browser_ = browser_;
+ browser_ = this;
+}
+
+NPBrowser::~NPBrowser() {
+ // Remove this browser from the linked list.
+ DCHECK(browser_ == this);
+ browser_ = previous_browser_;
+}
+
+NPIdentifier NPBrowser::GetStringIdentifier(const NPUTF8* name) {
+ return netscape_funcs_->getstringidentifier(name);
+}
+
+void* NPBrowser::MemAlloc(size_t size) {
+ return netscape_funcs_->memalloc(size);
+}
+
+void NPBrowser::MemFree(void* p) {
+ netscape_funcs_->memfree(p);
+}
+
+NPObject* NPBrowser::CreateObject(NPP npp, const NPClass* cl) {
+ return netscape_funcs_->createobject(npp, const_cast<NPClass*>(cl));
+}
+
+NPObject* NPBrowser::RetainObject(NPObject* object) {
+ return netscape_funcs_->retainobject(object);
+}
+
+void NPBrowser::ReleaseObject(NPObject* object) {
+ netscape_funcs_->releaseobject(object);
+}
+
+void NPBrowser::ReleaseVariantValue(NPVariant* variant) {
+ netscape_funcs_->releasevariantvalue(variant);
+}
+
+bool NPBrowser::HasProperty(NPP npp,
+ NPObject* object,
+ NPIdentifier name) {
+ return netscape_funcs_->hasproperty(npp, object, name);
+}
+
+bool NPBrowser::GetProperty(NPP npp,
+ NPObject* object,
+ NPIdentifier name,
+ NPVariant* result) {
+ return netscape_funcs_->getproperty(npp, object, name, result);
+}
+
+bool NPBrowser::SetProperty(NPP npp,
+ NPObject* object,
+ NPIdentifier name,
+ const NPVariant* result) {
+ return netscape_funcs_->setproperty(npp, object, name, result);
+}
+
+bool NPBrowser::RemoveProperty(NPP npp,
+ NPObject* object,
+ NPIdentifier name) {
+ return netscape_funcs_->removeproperty(npp, object, name);
+}
+
+bool NPBrowser::HasMethod(NPP npp,
+ NPObject* object,
+ NPIdentifier name) {
+ return netscape_funcs_->hasmethod(npp, object, name);
+}
+
+bool NPBrowser::Invoke(NPP npp,
+ NPObject* object,
+ NPIdentifier name,
+ const NPVariant* args,
+ uint32_t num_args,
+ NPVariant* result) {
+ return netscape_funcs_->invoke(npp, object, name, args, num_args, result);
+}
+
+NPObject* NPBrowser::GetWindowNPObject(NPP npp) {
+ NPObject* window;
+ if (NPERR_NO_ERROR == netscape_funcs_->getvalue(npp,
+ NPNVWindowNPObject,
+ &window)) {
+ return window;
+ } else {
+ return NULL;
+ }
+}
+
+void NPBrowser::PluginThreadAsyncCall(NPP npp,
+ PluginThreadAsyncCallProc callback,
+ void* data) {
+ netscape_funcs_->pluginthreadasynccall(npp, callback, data);
+}
+
+uint32 NPBrowser::ScheduleTimer(NPP npp,
+ uint32 interval,
+ bool repeat,
+ TimerProc callback) {
+ return netscape_funcs_->scheduletimer(npp, interval, repeat, callback);
+}
+
+void NPBrowser::UnscheduleTimer(NPP npp, uint32 timer_id) {
+ netscape_funcs_->unscheduletimer(npp, timer_id);
+}
+
+} // namespace np_utils
diff --git a/gpu/np_utils/np_browser.h b/gpu/np_utils/np_browser.h
new file mode 100644
index 0000000..e46bf38
--- /dev/null
+++ b/gpu/np_utils/np_browser.h
@@ -0,0 +1,95 @@
+// Copyright (c) 2006-2008 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.
+
+#ifndef GPU_NP_UTILS_NP_BROWSER_H_
+#define GPU_NP_UTILS_NP_BROWSER_H_
+
+#include "base/basictypes.h"
+#include "gpu/np_utils/np_headers.h"
+
+typedef struct _NPNetscapeFuncs NPNetscapeFuncs;
+
+namespace np_utils {
+
+// This class exposes the functions provided by the browser to a plugin (the
+// ones prefixed NPN_).
+class NPBrowser {
+ public:
+ explicit NPBrowser(NPNetscapeFuncs* funcs);
+ virtual ~NPBrowser();
+
+ static NPBrowser* get() {
+ return browser_;
+ }
+
+ // Standard functions from NPNetscapeFuncs.
+
+ virtual NPIdentifier GetStringIdentifier(const NPUTF8* name);
+
+ virtual void* MemAlloc(size_t size);
+
+ virtual void MemFree(void* p);
+
+ virtual NPObject* CreateObject(NPP npp, const NPClass* cl);
+
+ virtual NPObject* RetainObject(NPObject* object);
+
+ virtual void ReleaseObject(NPObject* object);
+
+ virtual void ReleaseVariantValue(NPVariant* variant);
+
+ virtual bool HasProperty(NPP npp,
+ NPObject* object,
+ NPIdentifier name);
+
+ virtual bool GetProperty(NPP npp,
+ NPObject* object,
+ NPIdentifier name,
+ NPVariant* result);
+
+ virtual bool SetProperty(NPP npp,
+ NPObject* object,
+ NPIdentifier name,
+ const NPVariant* result);
+
+ virtual bool RemoveProperty(NPP npp,
+ NPObject* object,
+ NPIdentifier name);
+
+ virtual bool HasMethod(NPP npp,
+ NPObject* object,
+ NPIdentifier name);
+
+ virtual bool Invoke(NPP npp,
+ NPObject* object,
+ NPIdentifier name,
+ const NPVariant* args,
+ uint32_t num_args,
+ NPVariant* result);
+
+ virtual NPObject* GetWindowNPObject(NPP npp);
+
+ typedef void (*PluginThreadAsyncCallProc)(void* data);
+ virtual void PluginThreadAsyncCall(NPP npp,
+ PluginThreadAsyncCallProc callback,
+ void* data);
+
+ typedef void (*TimerProc)(NPP npp, uint32 timer_id);
+ virtual uint32 ScheduleTimer(NPP npp,
+ uint32 interval,
+ bool repeat,
+ TimerProc callback);
+
+ virtual void UnscheduleTimer(NPP npp, uint32 timer_id);
+
+ private:
+ static NPBrowser* browser_;
+ NPBrowser* previous_browser_;
+ NPNetscapeFuncs* netscape_funcs_;
+ DISALLOW_COPY_AND_ASSIGN(NPBrowser);
+};
+
+} // namespace np_utils
+
+#endif // GPU_NP_UTILS_NP_BROWSER_H_
diff --git a/gpu/np_utils/np_browser_mock.h b/gpu/np_utils/np_browser_mock.h
new file mode 100644
index 0000000..c5361c7
--- /dev/null
+++ b/gpu/np_utils/np_browser_mock.h
@@ -0,0 +1,50 @@
+// Copyright (c) 2006-2008 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.
+
+#ifndef GPU_NP_UTILS_NP_BROWSER_MOCK_H_
+#define GPU_NP_UTILS_NP_BROWSER_MOCK_H_
+
+#include "gpu/np_utils/np_browser_stub.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace np_utils {
+
+// This mocks certain member functions of the stub browser. Those relating
+// to identifiers, memory management, reference counting and forwarding to
+// NPObjects are deliberately not mocked so the mock browser can be used as
+// normal for these calls.
+class MockNPBrowser : public StubNPBrowser {
+ public:
+ NPObject* ConcreteCreateObject(NPP npp, const NPClass* cl) {
+ return StubNPBrowser::CreateObject(npp, cl);
+ }
+
+ MockNPBrowser() {
+ // Do not mock CreateObject by default but allow it to be mocked so object
+ // creation can be intercepted.
+ ON_CALL(*this, CreateObject(testing::_, testing::_))
+ .WillByDefault(testing::Invoke(this,
+ &MockNPBrowser::ConcreteCreateObject));
+ }
+
+ void ConcretePluginThreadAsyncCall(NPP npp,
+ PluginThreadAsyncCallProc callback,
+ void* data) {
+ return StubNPBrowser::PluginThreadAsyncCall(npp, callback, data);
+ }
+
+ MOCK_METHOD2(CreateObject, NPObject*(NPP npp, const NPClass* cl));
+ MOCK_METHOD1(GetWindowNPObject, NPObject*(NPP cpp));
+ MOCK_METHOD3(PluginThreadAsyncCall,
+ void(NPP npp, PluginThreadAsyncCallProc callback, void* data));
+ MOCK_METHOD4(ScheduleTimer, uint32(NPP npp,
+ uint32 interval,
+ bool repeat,
+ TimerProc callback));
+ MOCK_METHOD2(UnscheduleTimer, void(NPP npp, uint32 timer_id));
+};
+
+} // namespace np_utils
+
+#endif // GPU_NP_UTILS_NP_BROWSER_MOCK_H_
diff --git a/gpu/np_utils/np_browser_stub.cc b/gpu/np_utils/np_browser_stub.cc
new file mode 100644
index 0000000..2e1c757
--- /dev/null
+++ b/gpu/np_utils/np_browser_stub.cc
@@ -0,0 +1,125 @@
+// Copyright (c) 2006-2008 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 "gpu/np_utils/np_browser_stub.h"
+#include "base/logging.h"
+#include "base/message_loop.h"
+
+namespace np_utils {
+
+StubNPBrowser::StubNPBrowser() : NPBrowser(NULL) {
+}
+
+StubNPBrowser::~StubNPBrowser() {
+}
+
+NPIdentifier StubNPBrowser::GetStringIdentifier(const NPUTF8* name) {
+ static std::set<std::string> names;
+ std::set<std::string>::iterator it = names.find(name);
+ if (it == names.end()) {
+ it = names.insert(name).first;
+ }
+ return const_cast<NPUTF8*>((*it).c_str());
+}
+
+void* StubNPBrowser::MemAlloc(size_t size) {
+ return malloc(size);
+}
+
+void StubNPBrowser::MemFree(void* p) {
+ free(p);
+}
+
+NPObject* StubNPBrowser::CreateObject(NPP npp, const NPClass* cl) {
+ NPObject* object = cl->allocate(npp, const_cast<NPClass*>(cl));
+ object->referenceCount = 1;
+ object->_class = const_cast<NPClass*>(cl);
+ return object;
+}
+
+NPObject* StubNPBrowser::RetainObject(NPObject* object) {
+ ++object->referenceCount;
+ return object;
+}
+
+void StubNPBrowser::ReleaseObject(NPObject* object) {
+ DCHECK_GE(object->referenceCount, 0u);
+ --object->referenceCount;
+ if (object->referenceCount == 0) {
+ object->_class->deallocate(object);
+ }
+}
+
+void StubNPBrowser::ReleaseVariantValue(NPVariant* variant) {
+ if (NPVARIANT_IS_STRING(*variant)) {
+ MemFree(const_cast<NPUTF8*>(variant->value.stringValue.UTF8Characters));
+ } else if (NPVARIANT_IS_OBJECT(*variant)) {
+ ReleaseObject(NPVARIANT_TO_OBJECT(*variant));
+ }
+}
+
+bool StubNPBrowser::HasProperty(NPP npp,
+ NPObject* object,
+ NPIdentifier name) {
+ return object->_class->hasProperty(object, name);
+}
+
+bool StubNPBrowser::GetProperty(NPP npp,
+ NPObject* object,
+ NPIdentifier name,
+ NPVariant* result) {
+ return object->_class->getProperty(object, name, result);
+}
+
+bool StubNPBrowser::SetProperty(NPP npp,
+ NPObject* object,
+ NPIdentifier name,
+ const NPVariant* result) {
+ return object->_class->setProperty(object, name, result);
+}
+
+bool StubNPBrowser::RemoveProperty(NPP npp,
+ NPObject* object,
+ NPIdentifier name) {
+ return object->_class->removeProperty(object, name);
+}
+
+bool StubNPBrowser::HasMethod(NPP npp,
+ NPObject* object,
+ NPIdentifier name) {
+ return object->_class->hasMethod(object, name);
+}
+
+bool StubNPBrowser::Invoke(NPP npp,
+ NPObject* object,
+ NPIdentifier name,
+ const NPVariant* args,
+ uint32_t num_args,
+ NPVariant* result) {
+ return object->_class->invoke(object, name, args, num_args, result);
+}
+
+NPObject* StubNPBrowser::GetWindowNPObject(NPP npp) {
+ return NULL;
+}
+
+void StubNPBrowser::PluginThreadAsyncCall(
+ NPP npp,
+ PluginThreadAsyncCallProc callback,
+ void* data) {
+ MessageLoop::current()->PostTask(FROM_HERE,
+ NewRunnableFunction(callback, data));
+}
+
+uint32 StubNPBrowser::ScheduleTimer(NPP npp,
+ uint32 interval,
+ bool repeat,
+ TimerProc callback) {
+ return 0;
+}
+
+void StubNPBrowser::UnscheduleTimer(NPP npp, uint32 timer_id) {
+}
+
+} // namespace np_utils
diff --git a/gpu/np_utils/np_browser_stub.h b/gpu/np_utils/np_browser_stub.h
new file mode 100644
index 0000000..f208b7b
--- /dev/null
+++ b/gpu/np_utils/np_browser_stub.h
@@ -0,0 +1,84 @@
+// Copyright (c) 2006-2008 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.
+
+#ifndef GPU_NP_UTILS_NP_BROWSER_STUB_H_
+#define GPU_NP_UTILS_NP_BROWSER_STUB_H_
+
+#include <set>
+#include <string>
+
+#include "gpu/np_utils/np_browser.h"
+
+namespace np_utils {
+
+// Simple implementation of subset of the NPN functions for testing.
+class StubNPBrowser : public NPBrowser {
+ public:
+ StubNPBrowser();
+ virtual ~StubNPBrowser();
+
+ // Standard functions from NPNetscapeFuncs.
+
+ virtual NPIdentifier GetStringIdentifier(const NPUTF8* name);
+
+ virtual void* MemAlloc(size_t size);
+
+ virtual void MemFree(void* p);
+
+ virtual NPObject* CreateObject(NPP npp, const NPClass* cl);
+
+ virtual NPObject* RetainObject(NPObject* object);
+
+ virtual void ReleaseObject(NPObject* object);
+
+ virtual void ReleaseVariantValue(NPVariant* variant);
+
+ virtual bool HasProperty(NPP npp,
+ NPObject* object,
+ NPIdentifier name);
+
+ virtual bool GetProperty(NPP npp,
+ NPObject* object,
+ NPIdentifier name,
+ NPVariant* result);
+
+ virtual bool SetProperty(NPP npp,
+ NPObject* object,
+ NPIdentifier name,
+ const NPVariant* result);
+
+ virtual bool RemoveProperty(NPP npp,
+ NPObject* object,
+ NPIdentifier name);
+
+ virtual bool HasMethod(NPP npp,
+ NPObject* object,
+ NPIdentifier name);
+ virtual bool Invoke(NPP npp,
+ NPObject* object,
+ NPIdentifier name,
+ const NPVariant* args,
+ uint32_t num_args,
+ NPVariant* result);
+
+ virtual NPObject* GetWindowNPObject(NPP npp);
+
+ virtual void PluginThreadAsyncCall(NPP npp,
+ PluginThreadAsyncCallProc callback,
+ void* data);
+
+ virtual uint32 ScheduleTimer(NPP npp,
+ uint32 interval,
+ bool repeat,
+ TimerProc callback);
+
+ virtual void UnscheduleTimer(NPP npp, uint32 timer_id);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(StubNPBrowser);
+};
+
+} // namespace np_utils
+
+#endif // GPU_NP_UTILS_NP_BROWSER_STUB_H_
diff --git a/gpu/np_utils/np_class.h b/gpu/np_utils/np_class.h
new file mode 100644
index 0000000..21d1d4b
--- /dev/null
+++ b/gpu/np_utils/np_class.h
@@ -0,0 +1,125 @@
+// Copyright (c) 2006-2008 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.
+
+#ifndef GPU_NP_UTILS_NP_CLASS_H_
+#define GPU_NP_UTILS_NP_CLASS_H_
+
+#include "gpu/np_utils/np_object_pointer.h"
+#include "gpu/np_utils/np_headers.h"
+
+// This file implements NPGetClass<T>. This function returns an NPClass
+// that can be used to instantiate an NPObject subclass T. The NPClass
+// function pointers will invoke the most derived corresponding member
+// functions in T.
+
+namespace np_utils {
+
+namespace np_class_impl {
+ // This template version of the NPClass allocate function creates a subclass
+ // of BaseNPObject.
+ template <typename NPObjectType>
+ static NPObject* Allocate(NPP npp, NPClass*) {
+ return new NPObjectType(npp);
+ }
+
+ // These implementations of the NPClass functions forward to the virtual
+ // functions in DefaultNPObject.
+ template <typename NPObjectType>
+ static void Deallocate(NPObject* object) {
+ delete static_cast<NPObjectType*>(object);
+ }
+
+ template <typename NPObjectType>
+ static void Invalidate(NPObject* object) {
+ return static_cast<NPObjectType*>(object)->Invalidate();
+ }
+
+ template <typename NPObjectType>
+ static bool HasMethod(NPObject* object, NPIdentifier name) {
+ return static_cast<NPObjectType*>(object)->HasMethod(name);
+ }
+
+ template <typename NPObjectType>
+ static bool Invoke(NPObject* object,
+ NPIdentifier name,
+ const NPVariant* args,
+ uint32_t num_args,
+ NPVariant* result) {
+ return static_cast<NPObjectType*>(object)->Invoke(
+ name, args, num_args, result);
+ }
+
+ template <typename NPObjectType>
+ static bool InvokeDefault(NPObject* object,
+ const NPVariant* args,
+ uint32_t num_args,
+ NPVariant* result) {
+ return static_cast<NPObjectType*>(object)->InvokeDefault(
+ args, num_args, result);
+ }
+
+ template <typename NPObjectType>
+ static bool HasProperty(NPObject* object, NPIdentifier name) {
+ return static_cast<NPObjectType*>(object)->HasProperty(name);
+ }
+
+ template <typename NPObjectType>
+ static bool GetProperty(NPObject* object,
+ NPIdentifier name,
+ NPVariant* result) {
+ return static_cast<NPObjectType*>(object)->GetProperty(name, result);
+ }
+
+ template <typename NPObjectType>
+ static bool SetProperty(NPObject* object,
+ NPIdentifier name,
+ const NPVariant* value) {
+ return static_cast<NPObjectType*>(object)->SetProperty(name, value);
+ }
+
+ template <typename NPObjectType>
+ static bool RemoveProperty(NPObject* object, NPIdentifier name) {
+ return static_cast<NPObjectType*>(object)->RemoveProperty(name);
+ }
+
+ template <typename NPObjectType>
+ static bool Enumerate(NPObject* object,
+ NPIdentifier** names,
+ uint32_t* count) {
+ return static_cast<NPObjectType*>(object)->Enumerate(names, count);
+ };
+
+ template <typename NPObjectType>
+ static bool Construct(NPObject* object,
+ const NPVariant* args,
+ uint32_t num_args,
+ NPVariant* result) {
+ return static_cast<NPObjectType*>(object)->Construct(
+ args, num_args, result);
+ }
+} // namespace np_class_impl;
+
+template <typename NPObjectType>
+const NPClass* NPGetClass() {
+ static const NPClass np_class = {
+ NP_CLASS_STRUCT_VERSION,
+ np_class_impl::Allocate<NPObjectType>,
+ np_class_impl::Deallocate<NPObjectType>,
+ np_class_impl::Invalidate<NPObjectType>,
+ np_class_impl::HasMethod<NPObjectType>,
+ np_class_impl::Invoke<NPObjectType>,
+ np_class_impl::InvokeDefault<NPObjectType>,
+ np_class_impl::HasProperty<NPObjectType>,
+ np_class_impl::GetProperty<NPObjectType>,
+ np_class_impl::SetProperty<NPObjectType>,
+ np_class_impl::RemoveProperty<NPObjectType>,
+ np_class_impl::Enumerate<NPObjectType>,
+ np_class_impl::Construct<NPObjectType>,
+ };
+ return &np_class;
+};
+
+} // namespace np_utils
+
+#endif // GPU_NP_UTILS_NP_CLASS_H_
diff --git a/gpu/np_utils/np_class_unittest.cc b/gpu/np_utils/np_class_unittest.cc
new file mode 100644
index 0000000..0e7807f
--- /dev/null
+++ b/gpu/np_utils/np_class_unittest.cc
@@ -0,0 +1,143 @@
+// Copyright (c) 2006-2008 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 "gpu/np_utils/np_class.h"
+#include "gpu/np_utils/np_object_mock.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::StrictMock;
+
+namespace np_utils {
+
+class NPClassTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ np_class = NPGetClass<StrictMock<MockNPObject> >();
+
+ // Dummy identifier is never used with real NPAPI so it can point to
+ // anything.
+ identifier = this;
+ }
+
+ virtual void TearDown() {
+ }
+
+ NPP_t npp_;
+ const NPClass* np_class;
+ NPIdentifier identifier;
+ NPVariant args[3];
+ NPVariant result;
+};
+
+TEST_F(NPClassTest, AllocateAndDeallocateObject) {
+ MockNPObject* object = static_cast<MockNPObject*>(
+ np_class->allocate(&npp_, const_cast<NPClass*>(np_class)));
+ EXPECT_TRUE(NULL != object);
+
+ np_class->deallocate(object);
+}
+
+TEST_F(NPClassTest, InvalidateForwards) {
+ MockNPObject* object = static_cast<MockNPObject*>(
+ np_class->allocate(&npp_, const_cast<NPClass*>(np_class)));
+
+ EXPECT_CALL(*object, Invalidate());
+ np_class->invalidate(object);
+
+ np_class->deallocate(object);
+}
+
+TEST_F(NPClassTest, HasMethodForwards) {
+ MockNPObject* object = static_cast<MockNPObject*>(
+ np_class->allocate(&npp_, const_cast<NPClass*>(np_class)));
+
+ EXPECT_CALL(*object, HasMethod(identifier));
+ np_class->hasMethod(object, identifier);
+
+ np_class->deallocate(object);
+}
+
+TEST_F(NPClassTest, InvokeForwards) {
+ MockNPObject* object = static_cast<MockNPObject*>(
+ np_class->allocate(&npp_, const_cast<NPClass*>(np_class)));
+
+ EXPECT_CALL(*object, Invoke(identifier, args, 3, &result));
+ np_class->invoke(object, identifier, args, 3, &result);
+
+ np_class->deallocate(object);
+}
+
+TEST_F(NPClassTest, InvokeDefaultForwards) {
+ MockNPObject* object = static_cast<MockNPObject*>(
+ np_class->allocate(&npp_, const_cast<NPClass*>(np_class)));
+
+ EXPECT_CALL(*object, InvokeDefault(args, 3, &result));
+ np_class->invokeDefault(object, args, 3, &result);
+
+ np_class->deallocate(object);
+}
+
+TEST_F(NPClassTest, HasPropertyForwards) {
+ MockNPObject* object = static_cast<MockNPObject*>(
+ np_class->allocate(&npp_, const_cast<NPClass*>(np_class)));
+
+ EXPECT_CALL(*object, HasProperty(identifier));
+ np_class->hasProperty(object, identifier);
+
+ np_class->deallocate(object);
+}
+
+TEST_F(NPClassTest, GetPropertyForwards) {
+ MockNPObject* object = static_cast<MockNPObject*>(
+ np_class->allocate(&npp_, const_cast<NPClass*>(np_class)));
+
+ EXPECT_CALL(*object, GetProperty(identifier, &result));
+ np_class->getProperty(object, identifier, &result);
+
+ np_class->deallocate(object);
+}
+
+TEST_F(NPClassTest, SetPropertyForwards) {
+ MockNPObject* object = static_cast<MockNPObject*>(
+ np_class->allocate(&npp_, const_cast<NPClass*>(np_class)));
+
+ EXPECT_CALL(*object, SetProperty(identifier, &result));
+ np_class->setProperty(object, identifier, &result);
+
+ np_class->deallocate(object);
+}
+
+TEST_F(NPClassTest, RemovePropertyForwards) {
+ MockNPObject* object = static_cast<MockNPObject*>(
+ np_class->allocate(&npp_, const_cast<NPClass*>(np_class)));
+
+ EXPECT_CALL(*object, RemoveProperty(identifier));
+ np_class->removeProperty(object, identifier);
+
+ np_class->deallocate(object);
+}
+
+TEST_F(NPClassTest, EnumerateForwards) {
+ MockNPObject* object = static_cast<MockNPObject*>(
+ np_class->allocate(&npp_, const_cast<NPClass*>(np_class)));
+
+ NPIdentifier* identifier = NULL;
+ uint32_t count;
+ EXPECT_CALL(*object, Enumerate(&identifier, &count));
+ np_class->enumerate(object, &identifier, &count);
+
+ np_class->deallocate(object);
+}
+
+TEST_F(NPClassTest, ConstructForwards) {
+ MockNPObject* object = static_cast<MockNPObject*>(
+ np_class->allocate(&npp_, const_cast<NPClass*>(np_class)));
+
+ EXPECT_CALL(*object, Construct(args, 3, &result));
+ np_class->construct(object, args, 3, &result);
+
+ np_class->deallocate(object);
+}
+} // namespace np_utils
diff --git a/gpu/np_utils/np_dispatcher.cc b/gpu/np_utils/np_dispatcher.cc
new file mode 100644
index 0000000..63293c0
--- /dev/null
+++ b/gpu/np_utils/np_dispatcher.cc
@@ -0,0 +1,86 @@
+// Copyright (c) 2006-2008 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 "gpu/np_utils/np_dispatcher.h"
+
+namespace np_utils {
+
+bool DispatcherHasMethodHelper(BaseNPDispatcher* chain,
+ NPObject* object,
+ NPIdentifier name) {
+ for (BaseNPDispatcher* dispatcher = chain;
+ dispatcher;
+ dispatcher = dispatcher->next()) {
+ if (dispatcher->name() == name) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool DispatcherInvokeHelper(BaseNPDispatcher* chain,
+ NPObject* object,
+ NPIdentifier name,
+ const NPVariant* args,
+ uint32_t num_args,
+ NPVariant* result) {
+ VOID_TO_NPVARIANT(*result);
+
+ for (BaseNPDispatcher* dispatcher = chain;
+ dispatcher;
+ dispatcher = dispatcher->next()) {
+ if (dispatcher->name() == name &&
+ dispatcher->num_args() == static_cast<int>(num_args)) {
+ if (dispatcher->Invoke(object, args, num_args, result))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool DispatcherEnumerateHelper(BaseNPDispatcher* chain,
+ NPObject* object,
+ NPIdentifier** names,
+ uint32_t* num_names) {
+ // Count the number of names.
+ *num_names = 0;
+ for (BaseNPDispatcher* dispatcher = chain;
+ dispatcher;
+ dispatcher = dispatcher->next()) {
+ ++(*num_names);
+ }
+
+ // Copy names into the array.
+ *names = static_cast<NPIdentifier*>(
+ NPBrowser::get()->MemAlloc((*num_names) * sizeof(**names)));
+ int i = 0;
+ for (BaseNPDispatcher* dispatcher = chain;
+ dispatcher;
+ dispatcher = dispatcher->next()) {
+ (*names)[i] = dispatcher->name();
+ ++i;
+ }
+
+ return true;
+}
+
+BaseNPDispatcher::BaseNPDispatcher(BaseNPDispatcher* next, const NPUTF8* name)
+ : next_(next) {
+ // Convert first character to lower case if it is the ASCII range.
+ // TODO(apatrick): do this correctly for non-ASCII characters.
+ std::string java_script_style_name(name);
+ if (isupper(java_script_style_name[0])) {
+ java_script_style_name[0] = tolower(java_script_style_name[0]);
+ }
+
+ name_ = NPBrowser::get()->GetStringIdentifier(
+ java_script_style_name.c_str());
+}
+
+BaseNPDispatcher::~BaseNPDispatcher() {
+}
+
+} // namespace np_utils
diff --git a/gpu/np_utils/np_dispatcher.h b/gpu/np_utils/np_dispatcher.h
new file mode 100644
index 0000000..ff6bed5
--- /dev/null
+++ b/gpu/np_utils/np_dispatcher.h
@@ -0,0 +1,224 @@
+// Copyright (c) 2006-2008 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.
+
+#ifndef GPU_NP_UTILS_NP_DISPATCHER_H_
+#define GPU_NP_UTILS_NP_DISPATCHER_H_
+
+#include <string>
+
+#include "gpu/np_utils/np_utils.h"
+#include "gpu/np_utils/np_headers.h"
+
+// Dispatchers make regular member functions available as NPObject methods.
+// Usage:
+//
+// class MyNPObject : public DefaultNPObject<NPObject> {
+// public:
+// int MyMethod(bool a, float b);
+// NP_UTILS_BEGIN_DISPATCHER_CHAIN(MyNPObject, DispatchedNPObject)
+// NP_UTILS_DISPATCHER(MyMethod, int(bool, float))
+// NP_UTILS_END_DISPATCHER_CHAIN
+// };
+//
+// Multiple member functions may be listed in the dispatcher chain. Inheritance
+// is supported. The following types are supported as return types and parameter
+// types:
+// * bool
+// * int
+// * float
+// * double
+// * std::string
+// * NPObject*
+//
+
+// These macros are used to make dispatcher chains.
+#define NP_UTILS_NP_UTILS_DISPATCHER_JOIN2(a, b) a ## b
+#define NP_UTILS_DISPATCHER_JOIN(a, b) NP_UTILS_NP_UTILS_DISPATCHER_JOIN2(a, b)
+#define NP_UTILS_DISPATCHER_UNIQUE \
+ NP_UTILS_DISPATCHER_JOIN(dispatcher, __LINE__)
+
+#define NP_UTILS_BEGIN_DISPATCHER_CHAIN(Class, BaseClass) \
+ static ::np_utils::BaseNPDispatcher* GetDispatcherChain() { \
+ typedef Class ThisClass; \
+ ::np_utils::BaseNPDispatcher* top_dispatcher = \
+ BaseClass::GetDispatcherChain(); \
+
+#define NP_UTILS_DISPATCHER(name, Signature) \
+ static ::np_utils::NPDispatcher<ThisClass, Signature> \
+ NP_UTILS_DISPATCHER_UNIQUE( \
+ top_dispatcher, \
+ #name, \
+ &ThisClass::name); \
+ top_dispatcher = &NP_UTILS_DISPATCHER_UNIQUE; \
+
+#define NP_UTILS_END_DISPATCHER_CHAIN \
+ return top_dispatcher; \
+ } \
+ bool HasMethod(NPIdentifier name) { \
+ return ::np_utils::DispatcherHasMethodHelper( \
+ GetDispatcherChain(), this, name); \
+ } \
+ bool Invoke(NPIdentifier name, \
+ const NPVariant* args, \
+ uint32_t num_args, \
+ NPVariant* result) { \
+ return ::np_utils::DispatcherInvokeHelper(GetDispatcherChain(), \
+ this, \
+ name, \
+ args, \
+ num_args, \
+ result); \
+ } \
+ bool Enumerate(NPIdentifier** names, uint32_t* num_names) { \
+ return ::np_utils::DispatcherEnumerateHelper(GetDispatcherChain(), \
+ this, \
+ names, \
+ num_names); \
+ } \
+
+namespace np_utils {
+
+class BaseNPDispatcher {
+ public:
+ BaseNPDispatcher(BaseNPDispatcher* next, const NPUTF8* name);
+
+ virtual ~BaseNPDispatcher();
+
+ BaseNPDispatcher* next() const {
+ return next_;
+ }
+
+ NPIdentifier name() const {
+ return name_;
+ }
+
+ virtual int num_args() const = 0;
+
+ virtual bool Invoke(NPObject* object,
+ const NPVariant* args,
+ uint32_t num_args,
+ NPVariant* result) = 0;
+
+ private:
+ BaseNPDispatcher* next_;
+ NPIdentifier name_;
+ DISALLOW_COPY_AND_ASSIGN(BaseNPDispatcher);
+};
+
+bool DispatcherHasMethodHelper(BaseNPDispatcher* chain,
+ NPObject* object,
+ NPIdentifier name);
+
+bool DispatcherInvokeHelper(BaseNPDispatcher* chain,
+ NPObject* object,
+ NPIdentifier name,
+ const NPVariant* args,
+ uint32_t num_args,
+ NPVariant* result);
+
+bool DispatcherEnumerateHelper(BaseNPDispatcher* chain,
+ NPObject* object,
+ NPIdentifier** names,
+ uint32_t* num_names);
+
+// This class should never be instantiated. It is always specialized. Attempting
+// to instantiate it results in a compilation error. This might mean an
+// attempt to instantiate a dispatcher with more parameters than have been
+// specialized for. See the specialization code below.
+template <typename NPObjectType, typename FunctionType>
+struct NPDispatcher {
+};
+
+#define TO_NPVARIANT(index) \
+ T##index n##index; \
+ if (!NPVariantToValue(&n##index, args[index])) \
+ return false; \
+
+#define NUM_PARAMS 0
+#define PARAM_TYPENAMES
+#define PARAM_TYPES
+#define PARAM_NAMES
+#define PARAM_DECLS // NOLINT
+
+#define PARAM_TO_NVPARIANT_CONVERSIONS \
+
+#include "gpu/np_utils/np_dispatcher_specializations.h" // NOLINT
+
+
+#define NUM_PARAMS 1
+#define PARAM_TYPENAMES , typename T0
+#define PARAM_TYPES T0
+#define PARAM_NAMES n0
+#define PARAM_DECLS T0 n0; // NOLINT
+
+#define PARAM_TO_NVPARIANT_CONVERSIONS \
+ TO_NPVARIANT(0); \
+
+#include "gpu/np_utils/np_dispatcher_specializations.h" // NOLINT
+
+
+#define NUM_PARAMS 2
+#define PARAM_TYPENAMES , typename T0, typename T1
+#define PARAM_TYPES T0, T1
+#define PARAM_NAMES n0, n1
+#define PARAM_DECLS T0 n0; T1 n1; // NOLINT
+
+#define PARAM_TO_NVPARIANT_CONVERSIONS \
+ TO_NPVARIANT(0); \
+ TO_NPVARIANT(1); \
+
+#include "gpu/np_utils/np_dispatcher_specializations.h" // NOLINT
+
+
+#define NUM_PARAMS 3
+#define PARAM_TYPENAMES , typename T0, typename T1, typename T2
+#define PARAM_TYPES T0, T1, T2
+#define PARAM_NAMES n0, n1, n2
+#define PARAM_DECLS T0 n0; T1 n1; T2 n2; // NOLINT
+
+#define PARAM_TO_NVPARIANT_CONVERSIONS \
+ TO_NPVARIANT(0); \
+ TO_NPVARIANT(1); \
+ TO_NPVARIANT(2); \
+
+#include "gpu/np_utils/np_dispatcher_specializations.h" // NOLINT
+
+
+#define NUM_PARAMS 4
+#define PARAM_TYPENAMES , typename T0, typename T1, typename T2, typename T3
+#define PARAM_TYPES T0, T1, T2, T3
+#define PARAM_NAMES n0, n1, n2, n3
+#define PARAM_DECLS T0 n0; T1 n1; T2 n2; T3 n3; // NOLINT
+
+#define PARAM_TO_NVPARIANT_CONVERSIONS \
+ TO_NPVARIANT(0); \
+ TO_NPVARIANT(1); \
+ TO_NPVARIANT(2); \
+ TO_NPVARIANT(3); \
+
+#include "gpu/np_utils/np_dispatcher_specializations.h" // NOLINT
+
+
+#define NUM_PARAMS 5
+#define PARAM_TYPENAMES , typename T0, typename T1, typename T2, typename T3, \
+ typename T4
+#define PARAM_TYPES T0, T1, T2, T3, T4
+#define PARAM_NAMES n0, n1, n2, n3, n4
+#define PARAM_DECLS T0 n0; T1 n1; T2 n2; T3 n3; T4 n4; // NOLINT
+
+#define PARAM_TO_NVPARIANT_CONVERSIONS \
+ TO_NPVARIANT(0); \
+ TO_NPVARIANT(1); \
+ TO_NPVARIANT(2); \
+ TO_NPVARIANT(3); \
+ TO_NPVARIANT(4); \
+
+#include "gpu/np_utils/np_dispatcher_specializations.h" // NOLINT
+
+
+#undef TO_NPVARIANT
+
+} // namespace np_utils
+
+#endif // GPU_NP_UTILS_NP_DISPATCHER_H_
diff --git a/gpu/np_utils/np_dispatcher_specializations.h b/gpu/np_utils/np_dispatcher_specializations.h
new file mode 100644
index 0000000..62fb8c4
--- /dev/null
+++ b/gpu/np_utils/np_dispatcher_specializations.h
@@ -0,0 +1,85 @@
+// Copyright (c) 2006-2008 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.
+
+// There is deliberately no header guard here. This file is included multiple
+// times, once for each dispatcher specialiation arity. Do not include this
+// file directly. Include np_dispatcher.h instead.
+
+template <typename NPObjectType PARAM_TYPENAMES>
+class NPDispatcher<NPObjectType, void(PARAM_TYPES)>
+ : public BaseNPDispatcher {
+ typedef void (NPObjectType::*FunctionType)(PARAM_TYPES);
+ public:
+ NPDispatcher(BaseNPDispatcher* next,
+ const NPUTF8* name,
+ FunctionType function)
+ : BaseNPDispatcher(next, name),
+ function_(function) {
+ }
+
+ virtual bool Invoke(NPObject* object,
+ const NPVariant* args,
+ uint32_t num_args,
+ NPVariant* result) {
+ VOID_TO_NPVARIANT(*result);
+
+ if (num_args != NUM_PARAMS)
+ return false;
+
+ PARAM_TO_NVPARIANT_CONVERSIONS
+
+ (static_cast<NPObjectType*>(object)->*function_)(PARAM_NAMES);
+ return true;
+ }
+
+ virtual int num_args() const {
+ return NUM_PARAMS;
+ }
+
+ private:
+ FunctionType function_;
+};
+
+template <typename NPObjectType, typename R PARAM_TYPENAMES>
+class NPDispatcher<NPObjectType, R(PARAM_TYPES)>
+ : public BaseNPDispatcher {
+ typedef R (NPObjectType::*FunctionType)(PARAM_TYPES);
+ public:
+ NPDispatcher(BaseNPDispatcher* next,
+ const NPUTF8* name,
+ FunctionType function)
+ : BaseNPDispatcher(next, name),
+ function_(function) {
+ }
+
+ virtual bool Invoke(NPObject* object,
+ const NPVariant* args,
+ uint32_t num_args,
+ NPVariant* result) {
+ VOID_TO_NPVARIANT(*result);
+
+ if (num_args != NUM_PARAMS)
+ return false;
+
+ PARAM_TO_NVPARIANT_CONVERSIONS
+
+ ValueToNPVariant(
+ (static_cast<NPObjectType*>(object)->*function_)(PARAM_NAMES), result);
+ return true;
+ }
+
+ virtual int num_args() const {
+ return NUM_PARAMS;
+ }
+
+ private:
+ FunctionType function_;
+};
+
+#undef NUM_PARAMS
+#undef PARAM_TYPENAMES
+#undef PARAM_TYPES
+#undef PARAM_NAMES
+#undef PARAM_DECLS
+#undef PARAM_TO_NVPARIANT_CONVERSIONS
diff --git a/gpu/np_utils/np_headers.h b/gpu/np_utils/np_headers.h
new file mode 100644
index 0000000..cd4d8f9
--- /dev/null
+++ b/gpu/np_utils/np_headers.h
@@ -0,0 +1,11 @@
+// Copyright (c) 2006-2008 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.
+
+#ifndef GPU_NP_UTILS_NP_HEADERS_H_
+#define GPU_NP_UTILS_NP_HEADERS_H_
+
+#include "third_party/npapi/bindings/npapi.h"
+#include "third_party/npapi/bindings/npruntime.h"
+
+#endif // GPU_NP_UTILS_NP_HEADERS_H_
diff --git a/gpu/np_utils/np_object_mock.h b/gpu/np_utils/np_object_mock.h
new file mode 100644
index 0000000..99d1ff6
--- /dev/null
+++ b/gpu/np_utils/np_object_mock.h
@@ -0,0 +1,36 @@
+// Copyright (c) 2006-2008 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.
+
+#ifndef GPU_NP_UTILS_NP_OBJECT_MOCK_H_
+#define GPU_NP_UTILS_NP_OBJECT_MOCK_H_
+
+#include "gpu/np_utils/np_browser.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace np_utils {
+
+class MockNPObject : public NPObject {
+ public:
+ explicit MockNPObject(NPP npp) {
+ }
+
+ MOCK_METHOD0(Invalidate, void());
+ MOCK_METHOD1(HasMethod, bool(NPIdentifier));
+ MOCK_METHOD4(Invoke,
+ bool(NPIdentifier, const NPVariant*, uint32_t, NPVariant*));
+ MOCK_METHOD3(InvokeDefault, bool(const NPVariant*, uint32_t, NPVariant*));
+ MOCK_METHOD1(HasProperty, bool(NPIdentifier));
+ MOCK_METHOD2(GetProperty, bool(NPIdentifier, NPVariant*));
+ MOCK_METHOD2(SetProperty, bool(NPIdentifier, const NPVariant*));
+ MOCK_METHOD1(RemoveProperty, bool(NPIdentifier));
+ MOCK_METHOD2(Enumerate, bool(NPIdentifier**, uint32_t*));
+ MOCK_METHOD3(Construct, bool(const NPVariant*, uint32_t, NPVariant*));
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockNPObject);
+};
+
+} // namespace np_utils
+
+#endif // GPU_NP_UTILS_NP_OBJECT_MOCK_H_
diff --git a/gpu/np_utils/np_object_pointer.h b/gpu/np_utils/np_object_pointer.h
new file mode 100644
index 0000000..44286a7
--- /dev/null
+++ b/gpu/np_utils/np_object_pointer.h
@@ -0,0 +1,119 @@
+// Copyright (c) 2006-2008 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.
+
+#ifndef GPU_NP_UTILS_NP_OBJECT_POINTER_H_
+#define GPU_NP_UTILS_NP_OBJECT_POINTER_H_
+
+#include "base/logging.h"
+#include "gpu/np_utils/np_browser.h"
+#include "gpu/np_utils/np_headers.h"
+
+namespace np_utils {
+
+// Smart pointer for NPObjects that automatically handles reference counting.
+template <typename NPObjectType>
+class NPObjectPointer {
+ public:
+ NPObjectPointer() : object_(NULL) {}
+
+ NPObjectPointer(const NPObjectPointer& rhs) : object_(rhs.object_) {
+ Retain();
+ }
+
+ explicit NPObjectPointer(NPObjectType* p) : object_(p) {
+ Retain();
+ }
+
+ template <typename RHS>
+ NPObjectPointer(const NPObjectPointer<RHS>& rhs) : object_(rhs.Get()) {
+ Retain();
+ }
+
+ ~NPObjectPointer() {
+ Release();
+ }
+
+ NPObjectPointer& operator=(const NPObjectPointer& rhs) {
+ if (object_ == rhs.Get())
+ return *this;
+
+ Release();
+ object_ = rhs.object_;
+ Retain();
+ return *this;
+ }
+
+ template <typename RHS>
+ NPObjectPointer& operator=(const NPObjectPointer<RHS>& rhs) {
+ if (object_ == rhs.Get())
+ return *this;
+
+ Release();
+ object_ = rhs.Get();
+ Retain();
+ return *this;
+ }
+
+ template <class RHS>
+ bool operator==(const NPObjectPointer<RHS>& rhs) const {
+ return object_ == rhs.Get();
+ }
+
+ template <class RHS>
+ bool operator!=(const NPObjectPointer<RHS>& rhs) const {
+ return object_ != rhs.Get();
+ }
+
+ // The NPObject convention for returning an NPObject pointer from a function
+ // is that the caller is responsible for releasing the reference count.
+ static NPObjectPointer FromReturned(NPObjectType* p) {
+ NPObjectPointer pointer(p);
+ pointer.Release();
+ return pointer;
+ }
+
+ // The NPObject convention for returning an NPObject pointer from a function
+ // is that the caller is responsible for releasing the reference count.
+ NPObjectType* ToReturned() const {
+ Retain();
+ return object_;
+ }
+
+ NPObjectType* Get() const {
+ return object_;
+ }
+
+ NPObjectType* operator->() const {
+ return object_;
+ }
+
+ NPObjectType& operator*() const {
+ return *object_;
+ }
+
+ private:
+ void Retain() const {
+ if (object_) {
+ NPBrowser::get()->RetainObject(object_);
+ }
+ }
+
+ void Release() const {
+ if (object_) {
+ NPBrowser::get()->ReleaseObject(object_);
+ }
+ }
+
+ NPObjectType* object_;
+};
+
+// For test diagnostics.
+template <typename NPObjectType>
+std::ostream& operator<<(std::ostream& stream,
+ const NPObjectPointer<NPObjectType>& pointer) {
+ return stream << pointer.Get();
+}
+} // namespace np_utils
+
+#endif // GPU_NP_UTILS_NP_OBJECT_POINTER_H_
diff --git a/gpu/np_utils/np_object_pointer_unittest.cc b/gpu/np_utils/np_object_pointer_unittest.cc
new file mode 100644
index 0000000..1e48453
--- /dev/null
+++ b/gpu/np_utils/np_object_pointer_unittest.cc
@@ -0,0 +1,220 @@
+// Copyright (c) 2006-2008 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 "gpu/np_utils/np_class.h"
+#include "gpu/np_utils/np_object_mock.h"
+#include "gpu/np_utils/np_browser_stub.h"
+#include "gpu/np_utils/np_object_pointer.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::Return;
+using testing::StrictMock;
+
+namespace np_utils {
+
+class DerivedNPObject : public MockNPObject {
+ public:
+ explicit DerivedNPObject(NPP npp) : MockNPObject(npp) {
+ }
+};
+
+class NPObjectPointerTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ np_class_ = NPGetClass<StrictMock<MockNPObject> >();
+
+ raw_pointer_ = static_cast<MockNPObject*>(
+ NPBrowser::get()->CreateObject(NULL, np_class_));
+
+ raw_derived_pointer_ = static_cast<DerivedNPObject*>(
+ NPBrowser::get()->CreateObject(NULL, np_class_));
+ }
+
+ virtual void TearDown() {
+ NPBrowser::get()->ReleaseObject(raw_pointer_);
+ NPBrowser::get()->ReleaseObject(raw_derived_pointer_);
+ }
+
+ StubNPBrowser stub_browser_;
+ const NPClass* np_class_;
+ MockNPObject* raw_pointer_;
+ DerivedNPObject* raw_derived_pointer_;
+};
+
+TEST_F(NPObjectPointerTest, PointerIsNullByDefault) {
+ NPObjectPointer<MockNPObject> p;
+ ASSERT_TRUE(NULL == p.Get());
+}
+
+TEST_F(NPObjectPointerTest, PointerCanBeExplicitlyConstructedFromRawPointer) {
+ EXPECT_EQ(1, raw_pointer_->referenceCount);
+ {
+ NPObjectPointer<MockNPObject> p(raw_pointer_);
+ ASSERT_TRUE(raw_pointer_ == p.Get());
+ EXPECT_EQ(2, raw_pointer_->referenceCount);
+ }
+ EXPECT_EQ(1, raw_pointer_->referenceCount);
+}
+
+TEST_F(NPObjectPointerTest,
+ PointerCanBeExplicitlyConstructedFromNullRawPointer) {
+ NPObjectPointer<MockNPObject> p(NULL);
+ ASSERT_TRUE(NULL == p.Get());
+}
+
+TEST_F(NPObjectPointerTest, PointerCanBeCopyConstructed) {
+ NPObjectPointer<MockNPObject> p1(raw_pointer_);
+ EXPECT_EQ(2, raw_pointer_->referenceCount);
+ {
+ NPObjectPointer<MockNPObject> p2(p1);
+ ASSERT_TRUE(raw_pointer_ == p2.Get());
+ EXPECT_EQ(3, raw_pointer_->referenceCount);
+ }
+ EXPECT_EQ(2, raw_pointer_->referenceCount);
+}
+
+TEST_F(NPObjectPointerTest, PointerCanBeConstructedFromDerived) {
+ NPObjectPointer<DerivedNPObject> p1(raw_derived_pointer_);
+ EXPECT_EQ(2, raw_derived_pointer_->referenceCount);
+ {
+ NPObjectPointer<MockNPObject> p2(p1);
+ ASSERT_TRUE(raw_derived_pointer_ == p2.Get());
+ EXPECT_EQ(3, raw_derived_pointer_->referenceCount);
+ }
+ EXPECT_EQ(2, raw_derived_pointer_->referenceCount);
+}
+
+TEST_F(NPObjectPointerTest,
+ PointerCanBeCopyConstructedFromNull) {
+ NPObjectPointer<MockNPObject> p(NULL);
+ ASSERT_TRUE(NULL == p.Get());
+}
+
+TEST_F(NPObjectPointerTest, PointerCanBeAssigned) {
+ NPObjectPointer<MockNPObject> p1(raw_pointer_);
+ EXPECT_EQ(2, raw_pointer_->referenceCount);
+ {
+ NPObjectPointer<MockNPObject> p2;
+ p2 = p1;
+ ASSERT_TRUE(raw_pointer_ == p2.Get());
+ EXPECT_EQ(3, raw_pointer_->referenceCount);
+
+ p2 = NPObjectPointer<MockNPObject>();
+ ASSERT_TRUE(NULL == p2.Get());
+ EXPECT_EQ(2, raw_pointer_->referenceCount);
+
+ p2 = p1;
+ ASSERT_TRUE(raw_pointer_ == p2.Get());
+ EXPECT_EQ(3, raw_pointer_->referenceCount);
+ }
+ EXPECT_EQ(2, raw_pointer_->referenceCount);
+}
+
+TEST_F(NPObjectPointerTest, PointerCanBeAssignedToSelf) {
+ NPObjectPointer<MockNPObject> p(raw_pointer_);
+ NPBrowser::get()->ReleaseObject(raw_pointer_);
+ EXPECT_EQ(1, raw_pointer_->referenceCount);
+ p = p;
+ EXPECT_EQ(1, raw_pointer_->referenceCount);
+ NPBrowser::get()->RetainObject(raw_pointer_);
+}
+
+TEST_F(NPObjectPointerTest, PointerCanBeAssignedDerived) {
+ NPObjectPointer<DerivedNPObject> p1(raw_derived_pointer_);
+ EXPECT_EQ(2, raw_derived_pointer_->referenceCount);
+ {
+ NPObjectPointer<MockNPObject> p2;
+ p2 = p1;
+ ASSERT_TRUE(raw_derived_pointer_ == p2.Get());
+ EXPECT_EQ(3, raw_derived_pointer_->referenceCount);
+
+ p2 = NPObjectPointer<MockNPObject>();
+ ASSERT_TRUE(NULL == p2.Get());
+ EXPECT_EQ(2, raw_derived_pointer_->referenceCount);
+
+ p2 = p1;
+ ASSERT_TRUE(raw_derived_pointer_ == p2.Get());
+ EXPECT_EQ(3, raw_derived_pointer_->referenceCount);
+ }
+ EXPECT_EQ(2, raw_derived_pointer_->referenceCount);
+}
+
+TEST_F(NPObjectPointerTest, DerivedPointerCanBeAssignedToSelf) {
+ NPObjectPointer<MockNPObject> p1(raw_derived_pointer_);
+ NPObjectPointer<DerivedNPObject> p2(raw_derived_pointer_);
+ NPBrowser::get()->ReleaseObject(raw_derived_pointer_);
+ NPBrowser::get()->ReleaseObject(raw_derived_pointer_);
+ EXPECT_EQ(1, raw_derived_pointer_->referenceCount);
+ p1 = p2;
+ EXPECT_EQ(1, raw_derived_pointer_->referenceCount);
+ NPBrowser::get()->RetainObject(raw_derived_pointer_);
+ NPBrowser::get()->RetainObject(raw_derived_pointer_);
+}
+
+TEST_F(NPObjectPointerTest, CanComparePointersForEqual) {
+ NPObjectPointer<MockNPObject> p1(raw_pointer_);
+ NPObjectPointer<DerivedNPObject> p2(raw_derived_pointer_);
+ EXPECT_TRUE(p1 == p1);
+ EXPECT_FALSE(p1 == p2);
+ EXPECT_FALSE(p2 == p1);
+ EXPECT_FALSE(p1 == NPObjectPointer<MockNPObject>());
+}
+
+TEST_F(NPObjectPointerTest, CanComparePointersForNotEqual) {
+ NPObjectPointer<MockNPObject> p1(raw_pointer_);
+ NPObjectPointer<DerivedNPObject> p2(raw_derived_pointer_);
+ EXPECT_FALSE(p1 != p1);
+ EXPECT_TRUE(p1 != p2);
+ EXPECT_TRUE(p2 != p1);
+ EXPECT_TRUE(p1 != NPObjectPointer<MockNPObject>());
+}
+
+TEST_F(NPObjectPointerTest, ArrowOperatorCanBeUsedToAccessNPObjectMembers) {
+ NPIdentifier name = NPBrowser::get()->GetStringIdentifier("hello");
+
+ EXPECT_CALL(*raw_pointer_, HasProperty(name)).WillOnce(Return(true));
+
+ NPObjectPointer<MockNPObject> p(raw_pointer_);
+ EXPECT_TRUE(p->HasProperty(name));
+}
+
+TEST_F(NPObjectPointerTest, StarOperatorReturnsNPObjectReference) {
+ NPObjectPointer<MockNPObject> p(raw_pointer_);
+ EXPECT_EQ(raw_pointer_, &*p);
+}
+
+TEST_F(NPObjectPointerTest, PointerCanBeConstructedFromReturnedNPObject) {
+ NPBrowser::get()->RetainObject(raw_pointer_);
+ EXPECT_EQ(2, raw_pointer_->referenceCount);
+ {
+ NPObjectPointer<MockNPObject> p(
+ NPObjectPointer<MockNPObject>::FromReturned(raw_pointer_));
+ EXPECT_EQ(2, raw_pointer_->referenceCount);
+ }
+ EXPECT_EQ(1, raw_pointer_->referenceCount);
+}
+
+TEST_F(NPObjectPointerTest, PointerCanBeConstructedFromReturnedNullNPObject) {
+ NPObjectPointer<MockNPObject> p(
+ NPObjectPointer<MockNPObject>::FromReturned(NULL));
+ EXPECT_TRUE(NULL == p.Get());
+}
+
+TEST_F(NPObjectPointerTest, PointerCanBeReturnedAsARawNPObject) {
+ NPObjectPointer<MockNPObject> p(raw_pointer_);
+ EXPECT_EQ(raw_pointer_, p.ToReturned());
+
+ // Check reference count is incremented before return for caller.
+ EXPECT_EQ(3, raw_pointer_->referenceCount);
+
+ NPBrowser::get()->ReleaseObject(raw_pointer_);
+}
+
+TEST_F(NPObjectPointerTest, NULLPointerCanBeReturnedAsARawNPObject) {
+ NPObjectPointer<MockNPObject> p;
+ EXPECT_TRUE(NULL == p.ToReturned());
+}
+
+} // namespace np_utils
diff --git a/gpu/np_utils/np_plugin_object.h b/gpu/np_utils/np_plugin_object.h
new file mode 100644
index 0000000..ad578e4
--- /dev/null
+++ b/gpu/np_utils/np_plugin_object.h
@@ -0,0 +1,50 @@
+// Copyright (c) 2006-2008 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.
+
+#ifndef GPU_NP_UTILS_NP_PLUGIN_OBJECT_H_
+#define GPU_NP_UTILS_NP_PLUGIN_OBJECT_H_
+
+#include "gpu/np_utils/np_object_pointer.h"
+#include "gpu/np_utils/np_headers.h"
+
+namespace np_utils {
+
+// Interface for a plugin instance. The NPP plugin calls forwards to an instance
+// of this interface.
+class PluginObject {
+ public:
+ // Initialize this object.
+ virtual NPError New(NPMIMEType plugin_type,
+ int16 argc,
+ char* argn[],
+ char* argv[],
+ NPSavedData* saved) = 0;
+
+ virtual NPError SetWindow(NPWindow* new_window) = 0;
+
+ virtual int16 HandleEvent(NPEvent* event) = 0;
+
+ // Uninitialize but do not deallocate the object. Release will be called to
+ // deallocate if Destroy succeeds.
+ virtual NPError Destroy(NPSavedData** saved) = 0;
+
+ // Deallocate this object. This object is invalid after this returns.
+ virtual void Release() = 0;
+
+ virtual NPObject* GetScriptableNPObject() = 0;
+
+ protected:
+ PluginObject() {
+ }
+
+ virtual ~PluginObject() {
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(PluginObject);
+};
+
+} // namespace np_utils
+
+#endif // GPU_NP_UTILS_NP_PLUGIN_OBJECT_H_
diff --git a/gpu/np_utils/np_plugin_object_factory.cc b/gpu/np_utils/np_plugin_object_factory.cc
new file mode 100644
index 0000000..7eedcc8
--- /dev/null
+++ b/gpu/np_utils/np_plugin_object_factory.cc
@@ -0,0 +1,30 @@
+// Copyright (c) 2006-2008 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 "gpu/gpu_plugin/gpu_plugin_object_factory.h"
+#include "base/logging.h"
+
+namespace np_utils {
+
+NPPluginObjectFactory* NPPluginObjectFactory::factory_;
+
+PluginObject* NPPluginObjectFactory::CreatePluginObject(
+ NPP npp,
+ NPMIMEType plugin_type) {
+ return NULL;
+}
+
+NPPluginObjectFactory::NPPluginObjectFactory() {
+ // Make this the first factory in the linked list.
+ previous_factory_ = factory_;
+ factory_ = this;
+}
+
+NPPluginObjectFactory::~NPPluginObjectFactory() {
+ // Remove this factory from the linked list.
+ DCHECK(factory_ == this);
+ factory_ = previous_factory_;
+}
+
+} // namespace np_utils
diff --git a/gpu/np_utils/np_plugin_object_factory.h b/gpu/np_utils/np_plugin_object_factory.h
new file mode 100644
index 0000000..969f5a3
--- /dev/null
+++ b/gpu/np_utils/np_plugin_object_factory.h
@@ -0,0 +1,37 @@
+// Copyright (c) 2006-2008 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.
+
+#ifndef GPU_NP_UTILS_NP_PLUGIN_OBJECT_FACTORY_H_
+#define GPU_NP_UTILS_NP_PLUGIN_OBJECT_FACTORY_H_
+
+#include "base/basictypes.h"
+#include "gpu/np_utils/np_headers.h"
+
+namespace np_utils {
+
+class PluginObject;
+
+// Mockable factory base class used to create instances of PluginObject based on
+// plugin mime type.
+class NPPluginObjectFactory {
+ public:
+ virtual PluginObject* CreatePluginObject(NPP npp, NPMIMEType plugin_type);
+
+ static NPPluginObjectFactory* get() {
+ return factory_;
+ }
+
+ protected:
+ NPPluginObjectFactory();
+ virtual ~NPPluginObjectFactory();
+
+ private:
+ static NPPluginObjectFactory* factory_;
+ NPPluginObjectFactory* previous_factory_;
+ DISALLOW_COPY_AND_ASSIGN(NPPluginObjectFactory);
+};
+
+} // namespace np_utils
+
+#endif // GPU_NP_UTILS_NP_PLUGIN_OBJECT_FACTORY_H_
diff --git a/gpu/np_utils/np_plugin_object_factory_mock.h b/gpu/np_utils/np_plugin_object_factory_mock.h
new file mode 100644
index 0000000..a09205c
--- /dev/null
+++ b/gpu/np_utils/np_plugin_object_factory_mock.h
@@ -0,0 +1,23 @@
+// Copyright (c) 2006-2008 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.
+
+#ifndef GPU_NP_UTILS_NP_PLUGIN_OBJECT_FACTORY_MOCK_H_
+#define GPU_NP_UTILS_NP_PLUGIN_OBJECT_FACTORY_MOCK_H_
+
+#include "gpu/np_utils/np_plugin_object_factory.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace np_utils {
+
+// Mockable factory used to create instances of PluginObject based on plugin
+// mime type.
+class MockPluginObjectFactory : public NPPluginObjectFactory {
+ public:
+ MOCK_METHOD2(CreatePluginObject, PluginObject*(NPP, NPMIMEType));
+};
+
+} // namespace np_utils
+
+#endif // GPU_NP_UTILS_NP_PLUGIN_OBJECT_FACTORY_MOCK_H_
diff --git a/gpu/np_utils/np_plugin_object_mock.h b/gpu/np_utils/np_plugin_object_mock.h
new file mode 100644
index 0000000..342b22c
--- /dev/null
+++ b/gpu/np_utils/np_plugin_object_mock.h
@@ -0,0 +1,26 @@
+// Copyright (c) 2006-2008 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.
+
+#ifndef GPU_NP_UTILS_NP_PLUGIN_OBJECT_MOCK_H_
+#define GPU_NP_UTILS_NP_PLUGIN_OBJECT_MOCK_H_
+
+#include "gpu/np_utils/np_plugin_object.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace np_utils {
+
+class MockPluginObject : public PluginObject {
+ public:
+ MOCK_METHOD5(New, NPError(NPMIMEType, int16, char*[], char*[], NPSavedData*));
+ MOCK_METHOD1(SetWindow, NPError(NPWindow*));
+ MOCK_METHOD1(HandleEvent, int16(NPEvent*));
+ MOCK_METHOD1(Destroy, NPError(NPSavedData**));
+ MOCK_METHOD0(Release, void());
+ MOCK_METHOD0(GetScriptableNPObject, NPObject*());
+};
+
+} // namespace np_utils
+
+#endif // GPU_NP_UTILS_NP_PLUGIN_OBJECT_MOCK_H_
diff --git a/gpu/np_utils/np_utils.cc b/gpu/np_utils/np_utils.cc
new file mode 100644
index 0000000..d6a15a4
--- /dev/null
+++ b/gpu/np_utils/np_utils.cc
@@ -0,0 +1,170 @@
+// Copyright (c) 2006-2008 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 "gpu/np_utils/np_utils.h"
+
+namespace np_utils {
+
+bool NPVariantToValue(bool* value, const NPVariant& variant) {
+ if (NPVARIANT_IS_BOOLEAN(variant)) {
+ *value = NPVARIANT_TO_BOOLEAN(variant);
+ return true;
+ }
+
+ return false;
+}
+
+bool NPVariantToValue(int32* value, const NPVariant& variant) {
+ if (NPVARIANT_IS_INT32(variant)) {
+ *value = NPVARIANT_TO_INT32(variant);
+ return true;
+ }
+
+ return false;
+}
+
+bool NPVariantToValue(float* value, const NPVariant& variant) {
+ if (NPVARIANT_IS_DOUBLE(variant)) {
+ *value = static_cast<float>(NPVARIANT_TO_DOUBLE(variant));
+ return true;
+ } else if (NPVARIANT_IS_INT32(variant)) {
+ *value = static_cast<float>(NPVARIANT_TO_INT32(variant));
+ return true;
+ }
+
+ return false;
+}
+
+bool NPVariantToValue(double* value, const NPVariant& variant) {
+ if (NPVARIANT_IS_DOUBLE(variant)) {
+ *value = NPVARIANT_TO_DOUBLE(variant);
+ return true;
+ } else if (NPVARIANT_IS_INT32(variant)) {
+ *value = NPVARIANT_TO_INT32(variant);
+ return true;
+ }
+
+ return false;
+}
+
+bool NPVariantToValue(std::string* value, const NPVariant& variant) {
+ if (NPVARIANT_IS_STRING(variant)) {
+ const NPString& str = NPVARIANT_TO_STRING(variant);
+ *value = std::string(str.UTF8Characters, str.UTF8Length);
+ return true;
+ }
+
+ return false;
+}
+
+void ValueToNPVariant(bool value, NPVariant* variant) {
+ BOOLEAN_TO_NPVARIANT(value, *variant);
+}
+
+void ValueToNPVariant(int32 value, NPVariant* variant) {
+ INT32_TO_NPVARIANT(value, *variant);
+}
+
+void ValueToNPVariant(float value, NPVariant* variant) {
+ DOUBLE_TO_NPVARIANT(value, *variant);
+}
+
+void ValueToNPVariant(double value, NPVariant* variant) {
+ DOUBLE_TO_NPVARIANT(value, *variant);
+}
+
+void ValueToNPVariant(const std::string& value, NPVariant* variant) {
+ NPUTF8* p = static_cast<NPUTF8*>(NPBrowser::get()->MemAlloc(value.length()));
+ memcpy(p, value.c_str(), value.length());
+ STRINGN_TO_NPVARIANT(p, value.length(), *variant);
+}
+
+SmartNPVariant::SmartNPVariant() {
+ VOID_TO_NPVARIANT(*this);
+}
+
+SmartNPVariant::SmartNPVariant(const SmartNPVariant& rhs) {
+ rhs.CopyTo(this);
+}
+
+SmartNPVariant::SmartNPVariant(const NPVariant& rhs) {
+ static_cast<const SmartNPVariant&>(rhs).CopyTo(this);
+}
+
+SmartNPVariant::~SmartNPVariant() {
+ Release();
+}
+
+SmartNPVariant& SmartNPVariant::operator=(const SmartNPVariant& rhs) {
+ Release();
+ rhs.CopyTo(this);
+ return *this;
+}
+
+SmartNPVariant& SmartNPVariant::operator=(const NPVariant& rhs) {
+ Release();
+ static_cast<const SmartNPVariant&>(rhs).CopyTo(this);
+ return *this;
+}
+
+bool SmartNPVariant::IsVoid() const {
+ return NPVARIANT_IS_VOID(*this);
+}
+
+void SmartNPVariant::Release() {
+ NPBrowser::get()->ReleaseVariantValue(this);
+ VOID_TO_NPVARIANT(*this);
+}
+
+void SmartNPVariant::Invalidate() {
+ if (NPVARIANT_IS_OBJECT(*this)) {
+ NULL_TO_NPVARIANT(*this);
+ }
+}
+
+void SmartNPVariant::CopyTo(NPVariant* rhs) const {
+ if (NPVARIANT_IS_OBJECT(*this)) {
+ NPObject* object = NPVARIANT_TO_OBJECT(*this);
+ OBJECT_TO_NPVARIANT(object, *rhs);
+ NPBrowser::get()->RetainObject(object);
+ } else if (NPVARIANT_IS_STRING(*this)) {
+ NPUTF8* copy = static_cast<NPUTF8*>(NPBrowser::get()->MemAlloc(
+ value.stringValue.UTF8Length));
+ memcpy(copy,
+ value.stringValue.UTF8Characters,
+ value.stringValue.UTF8Length);
+ STRINGN_TO_NPVARIANT(copy, value.stringValue.UTF8Length, *rhs);
+ } else {
+ memcpy(rhs, this, sizeof(*rhs));
+ }
+}
+
+bool NPHasMethod(NPP npp,
+ const NPObjectPointer<NPObject>& object,
+ const NPUTF8* name) {
+ return NPBrowser::get()->HasMethod(
+ npp,
+ object.Get(),
+ NPBrowser::get()->GetStringIdentifier(name));
+}
+
+bool NPHasProperty(NPP npp,
+ const NPObjectPointer<NPObject>& object,
+ const NPUTF8* name) {
+ return NPBrowser::get()->HasProperty(
+ npp,
+ object.Get(),
+ NPBrowser::get()->GetStringIdentifier(name));
+}
+
+bool NPRemoveProperty(NPP npp,
+ const NPObjectPointer<NPObject>& object,
+ const NPUTF8* name) {
+ return NPBrowser::get()->RemoveProperty(
+ npp,
+ object.Get(),
+ NPBrowser::get()->GetStringIdentifier(name));
+}
+
+} // namespace np_utils
diff --git a/gpu/np_utils/np_utils.h b/gpu/np_utils/np_utils.h
new file mode 100644
index 0000000..5c7e3b7
--- /dev/null
+++ b/gpu/np_utils/np_utils.h
@@ -0,0 +1,271 @@
+// Copyright (c) 2006-2008 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.
+
+#ifndef GPU_NP_UTILS_NP_UTILS_H_
+#define GPU_NP_UTILS_NP_UTILS_H_
+
+#include <string>
+
+#include "gpu/np_utils/np_browser.h"
+#include "gpu/np_utils/np_class.h"
+#include "gpu/np_utils/np_object_pointer.h"
+#include "gpu/np_utils/np_headers.h"
+
+namespace np_utils {
+
+// Convert NPVariant to C++ type. Returns whether the conversion was successful.
+bool NPVariantToValue(bool* value, const NPVariant& variant);
+bool NPVariantToValue(int32* value, const NPVariant& variant);
+bool NPVariantToValue(float* value, const NPVariant& variant);
+bool NPVariantToValue(double* value, const NPVariant& variant);
+bool NPVariantToValue(std::string* value, const NPVariant& variant);
+
+template <typename T>
+bool NPVariantToValue(NPObjectPointer<T>* value,
+ const NPVariant& variant) {
+ if (NPVARIANT_IS_NULL(variant)) {
+ *value = NPObjectPointer<T>();
+ return true;
+ } else if (NPVARIANT_IS_OBJECT(variant)) {
+ NPObject* object = NPVARIANT_TO_OBJECT(variant);
+ if (object->_class == NPGetClass<T>()) {
+ *value = NPObjectPointer<T>(static_cast<T*>(
+ NPVARIANT_TO_OBJECT(variant)));
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// Specialization for NPObject does not check for mismatched NPClass.
+template <>
+inline bool NPVariantToValue(NPObjectPointer<NPObject>* value,
+ const NPVariant& variant) {
+ if (NPVARIANT_IS_NULL(variant)) {
+ *value = NPObjectPointer<NPObject>();
+ return true;
+ } else if (NPVARIANT_IS_OBJECT(variant)) {
+ *value = NPObjectPointer<NPObject>(NPVARIANT_TO_OBJECT(variant));
+ return true;
+ }
+
+ return false;
+}
+
+// Convert C++ type to NPVariant.
+void ValueToNPVariant(bool value, NPVariant* variant);
+void ValueToNPVariant(int32 value, NPVariant* variant);
+void ValueToNPVariant(float value, NPVariant* variant);
+void ValueToNPVariant(double value, NPVariant* variant);
+void ValueToNPVariant(const std::string& value, NPVariant* variant);
+
+template <typename T>
+void ValueToNPVariant(const NPObjectPointer<T>& value,
+ NPVariant* variant) {
+ if (value.Get()) {
+ NPBrowser::get()->RetainObject(value.Get());
+ OBJECT_TO_NPVARIANT(value.Get(), *variant);
+ } else {
+ NULL_TO_NPVARIANT(*variant);
+ }
+}
+
+// NPVariant that automatically manages lifetime of string and object variants.
+class SmartNPVariant : public NPVariant {
+ public:
+ SmartNPVariant();
+ SmartNPVariant(const SmartNPVariant& rhs);
+ explicit SmartNPVariant(const NPVariant& rhs);
+
+ template <typename T>
+ explicit SmartNPVariant(const T& v) {
+ ValueToNPVariant(v, this);
+ }
+
+ ~SmartNPVariant();
+
+ SmartNPVariant& operator=(const SmartNPVariant& rhs);
+ SmartNPVariant& operator=(const NPVariant& rhs);
+
+ template <typename T>
+ bool GetValue(T* v) const {
+ return NPVariantToValue(v, *this);
+ }
+
+ bool IsVoid() const;
+
+ template <typename T>
+ void SetValue(const T& v) {
+ Release();
+ ValueToNPVariant(v, this);
+ }
+
+ void CopyTo(NPVariant* target) const;
+
+ // Sets the variant to void.
+ void Release();
+
+ // Called when an NPObject is invalidated to clear any references to other
+ // NPObjects. Does not release the object as it might no longer be valid.
+ void Invalidate();
+};
+
+// These allow a method to be invoked with automatic conversion of C++
+// types to variants for arguments and return values.
+
+bool NPHasMethod(NPP npp,
+ const NPObjectPointer<NPObject>& object,
+ const NPUTF8* name);
+
+inline bool NPInvokeVoid(NPP npp,
+ const NPObjectPointer<NPObject>& object,
+ const NPUTF8* name) {
+ SmartNPVariant result;
+ return NPBrowser::get()->Invoke(
+ npp,
+ object.Get(),
+ NPBrowser::get()->GetStringIdentifier(name),
+ NULL, 0,
+ &result);
+}
+
+template<typename R>
+bool NPInvoke(NPP npp,
+ const NPObjectPointer<NPObject>& object,
+ const NPUTF8* name,
+ R* r) {
+ SmartNPVariant result;
+ if (NPBrowser::get()->Invoke(
+ npp,
+ object.Get(),
+ NPBrowser::get()->GetStringIdentifier(name),
+ NULL, 0,
+ &result)) {
+ return result.GetValue(r);
+ }
+ return false;
+}
+
+template<typename P0>
+bool NPInvokeVoid(NPP npp,
+ const NPObjectPointer<NPObject>& object,
+ const NPUTF8* name,
+ P0 p0) {
+ SmartNPVariant args[1];
+ args[0].SetValue(p0);
+ SmartNPVariant result;
+ return NPBrowser::get()->Invoke(
+ npp,
+ object.Get(),
+ NPBrowser::get()->GetStringIdentifier(name),
+ &args[0], 1,
+ &result);
+}
+
+template<typename R, typename P0>
+bool NPInvoke(NPP npp,
+ const NPObjectPointer<NPObject>& object,
+ const NPUTF8* name,
+ P0 p0,
+ R* r) {
+ SmartNPVariant args[1];
+ args[0].SetValue(p0);
+ SmartNPVariant result;
+ if (NPBrowser::get()->Invoke(
+ npp,
+ object.Get(),
+ NPBrowser::get()->GetStringIdentifier(name),
+ &args[0], 1,
+ &result)) {
+ return result.GetValue(r);
+ }
+ return false;
+}
+
+template<typename P0, typename P1>
+bool NPInvokeVoid(NPP npp,
+ const NPObjectPointer<NPObject>& object,
+ const NPUTF8* name,
+ P0 p0, P1 p1) {
+ SmartNPVariant args[2];
+ args[0].SetValue(p0);
+ args[1].SetValue(p1);
+ SmartNPVariant result;
+ return NPBrowser::get()->Invoke(
+ npp,
+ object.Get(),
+ NPBrowser::get()->GetStringIdentifier(name),
+ &args[0], 2,
+ &result);
+}
+
+template<typename R, typename P0, typename P1>
+bool NPInvoke(NPP npp,
+ const NPObjectPointer<NPObject>& object,
+ const NPUTF8* name,
+ P0 p0, P1 p1,
+ R* r) {
+ SmartNPVariant args[2];
+ args[0].SetValue(p0);
+ args[1].SetValue(p1);
+ SmartNPVariant result;
+ if (NPBrowser::get()->Invoke(
+ npp,
+ object.Get(),
+ NPBrowser::get()->GetStringIdentifier(name),
+ &args[0], 2,
+ &result)) {
+ return result.GetValue(r);
+ }
+ return false;
+}
+
+bool NPHasProperty(NPP npp,
+ const NPObjectPointer<NPObject>& object,
+ const NPUTF8* name);
+
+template <typename T>
+bool NPGetProperty(NPP npp,
+ const NPObjectPointer<NPObject>& object,
+ const NPUTF8* name,
+ T* value) {
+ SmartNPVariant result;
+ if (NPBrowser::get()->GetProperty(npp,
+ object.Get(),
+ NPBrowser::get()->GetStringIdentifier(name),
+ &result)) {
+ return result.GetValue(value);
+ }
+ return false;
+}
+
+template <typename T>
+bool NPSetProperty(NPP npp,
+ const NPObjectPointer<NPObject>& object,
+ const NPUTF8* name,
+ const T& value) {
+ SmartNPVariant variant(value);
+ return NPBrowser::get()->SetProperty(
+ npp,
+ object.Get(),
+ NPBrowser::get()->GetStringIdentifier(name),
+ &variant);
+}
+
+bool NPRemoveProperty(NPP npp,
+ const NPObjectPointer<NPObject>& object,
+ const NPUTF8* name);
+
+template <typename NPObjectType>
+NPObjectPointer<NPObjectType> NPCreateObject(NPP npp) {
+ const NPClass* np_class = NPGetClass<NPObjectType>();
+ NPObjectType* object = static_cast<NPObjectType*>(
+ NPBrowser::get()->CreateObject(npp, np_class));
+ return NPObjectPointer<NPObjectType>::FromReturned(object);
+}
+
+} // namespace np_utils
+
+#endif // GPU_NP_UTILS_NP_UTILS_H_
diff --git a/gpu/np_utils/np_utils_unittest.cc b/gpu/np_utils/np_utils_unittest.cc
new file mode 100644
index 0000000..ceb87ad
--- /dev/null
+++ b/gpu/np_utils/np_utils_unittest.cc
@@ -0,0 +1,424 @@
+// Copyright (c) 2006-2008 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 "gpu/np_utils/np_object_mock.h"
+#include "gpu/np_utils/np_browser_stub.h"
+#include "gpu/np_utils/np_utils.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::_;
+using testing::DoAll;
+using testing::MakeMatcher;
+using testing::Matcher;
+using testing::Pointee;
+using testing::Return;
+using testing::SetArgumentPointee;
+using testing::StrictMock;
+
+namespace np_utils {
+
+class NPUtilsTest : public testing::Test {
+ protected:
+ StubNPBrowser stub_browser_;
+ NPP_t npp_;
+ NPVariant variant_;
+};
+
+TEST_F(NPUtilsTest, TestBoolNPVariantToValue) {
+ bool v;
+
+ BOOLEAN_TO_NPVARIANT(false, variant_);
+ EXPECT_TRUE(NPVariantToValue(&v, variant_));
+ EXPECT_FALSE(v);
+
+ BOOLEAN_TO_NPVARIANT(true, variant_);
+ EXPECT_TRUE(NPVariantToValue(&v, variant_));
+ EXPECT_TRUE(v);
+
+ INT32_TO_NPVARIANT(7, variant_);
+ EXPECT_FALSE(NPVariantToValue(&v, variant_));
+}
+
+TEST_F(NPUtilsTest, TestIntNPVariantToValue) {
+ INT32_TO_NPVARIANT(7, variant_);
+
+ int v1;
+ EXPECT_TRUE(NPVariantToValue(&v1, variant_));
+ EXPECT_EQ(7, v1);
+
+ float v2;
+ EXPECT_TRUE(NPVariantToValue(&v2, variant_));
+ EXPECT_EQ(7.0f, v2);
+
+ double v3;
+ EXPECT_TRUE(NPVariantToValue(&v3, variant_));
+ EXPECT_EQ(7.0, v3);
+
+ BOOLEAN_TO_NPVARIANT(false, variant_);
+ EXPECT_FALSE(NPVariantToValue(&v1, variant_));
+}
+
+TEST_F(NPUtilsTest, TestFloatNPVariantToValue) {
+ float v;
+
+ DOUBLE_TO_NPVARIANT(7.0, variant_);
+ EXPECT_TRUE(NPVariantToValue(&v, variant_));
+ EXPECT_EQ(7.0f, v);
+
+ BOOLEAN_TO_NPVARIANT(false, variant_);
+ EXPECT_FALSE(NPVariantToValue(&v, variant_));
+}
+
+TEST_F(NPUtilsTest, TestDoubleNPVariantToValue) {
+ double v;
+
+ DOUBLE_TO_NPVARIANT(7.0, variant_);
+ EXPECT_TRUE(NPVariantToValue(&v, variant_));
+ EXPECT_EQ(7.0, v);
+
+ BOOLEAN_TO_NPVARIANT(false, variant_);
+ EXPECT_FALSE(NPVariantToValue(&v, variant_));
+}
+
+TEST_F(NPUtilsTest, TestStringNPVariantToValue) {
+ std::string v;
+
+ STRINGZ_TO_NPVARIANT("hello", variant_);
+ EXPECT_TRUE(NPVariantToValue(&v, variant_));
+ EXPECT_EQ(std::string("hello"), v);
+
+ BOOLEAN_TO_NPVARIANT(false, variant_);
+ EXPECT_FALSE(NPVariantToValue(&v, variant_));
+}
+
+TEST_F(NPUtilsTest, TestObjectNPVariantToValue) {
+ NPObjectPointer<NPObject> object =
+ NPCreateObject<StrictMock<MockNPObject> >(NULL);
+ NPObjectPointer<NPObject> v;
+
+ OBJECT_TO_NPVARIANT(object.Get(), variant_);
+ EXPECT_TRUE(NPVariantToValue(&v, variant_));
+ EXPECT_EQ(object, v);
+
+ BOOLEAN_TO_NPVARIANT(false, variant_);
+ EXPECT_FALSE(NPVariantToValue(&v, variant_));
+}
+
+TEST_F(NPUtilsTest, TestNullNPVariantToValue) {
+ NPObjectPointer<NPObject> v;
+
+ NULL_TO_NPVARIANT(variant_);
+ EXPECT_TRUE(NPVariantToValue(&v, variant_));
+ EXPECT_TRUE(NPObjectPointer<NPObject>() == v);
+
+ BOOLEAN_TO_NPVARIANT(false, variant_);
+ EXPECT_FALSE(NPVariantToValue(&v, variant_));
+}
+
+TEST_F(NPUtilsTest, TestDerivedObjectNPVariantToValue) {
+ NPObjectPointer<NPObject> object =
+ NPCreateObject<StrictMock<MockNPObject> >(NULL);
+ NPObjectPointer<StrictMock<MockNPObject> > v;
+
+ OBJECT_TO_NPVARIANT(object.Get(), variant_);
+ EXPECT_TRUE(NPVariantToValue(&v, variant_));
+ EXPECT_EQ(object, v);
+}
+
+TEST_F(NPUtilsTest,
+ TestDerivedObjectNPVariantToValueFailsIfValueHasDifferentType) {
+ NPObjectPointer<NPObject> object =
+ NPCreateObject<StrictMock<MockNPObject> >(NULL);
+ NPObjectPointer<MockNPObject> v;
+
+ OBJECT_TO_NPVARIANT(object.Get(), variant_);
+ EXPECT_FALSE(NPVariantToValue(&v, variant_));
+}
+
+TEST_F(NPUtilsTest, TestBoolValueToNPVariant) {
+ ValueToNPVariant(true, &variant_);
+ EXPECT_TRUE(NPVARIANT_IS_BOOLEAN(variant_));
+ EXPECT_TRUE(NPVARIANT_TO_BOOLEAN(variant_));
+
+ ValueToNPVariant(false, &variant_);
+ EXPECT_TRUE(NPVARIANT_IS_BOOLEAN(variant_));
+ EXPECT_FALSE(NPVARIANT_TO_BOOLEAN(variant_));
+}
+
+TEST_F(NPUtilsTest, TestIntValueToNPVariant) {
+ ValueToNPVariant(7, &variant_);
+ EXPECT_TRUE(NPVARIANT_IS_INT32(variant_));
+ EXPECT_EQ(7, NPVARIANT_TO_INT32(variant_));
+}
+
+TEST_F(NPUtilsTest, TestFloatValueToNPVariant) {
+ ValueToNPVariant(7.0f, &variant_);
+ EXPECT_TRUE(NPVARIANT_IS_DOUBLE(variant_));
+ EXPECT_EQ(7.0, NPVARIANT_TO_DOUBLE(variant_));
+}
+
+TEST_F(NPUtilsTest, TestDoubleValueToNPVariant) {
+ ValueToNPVariant(7.0, &variant_);
+ EXPECT_TRUE(NPVARIANT_IS_DOUBLE(variant_));
+ EXPECT_EQ(7.0, NPVARIANT_TO_DOUBLE(variant_));
+}
+
+TEST_F(NPUtilsTest, TestStringValueToNPVariant) {
+ ValueToNPVariant(std::string("hello"), &variant_);
+ EXPECT_TRUE(NPVARIANT_IS_STRING(variant_));
+ EXPECT_EQ(std::string("hello"),
+ std::string(variant_.value.stringValue.UTF8Characters,
+ variant_.value.stringValue.UTF8Length));
+}
+
+TEST_F(NPUtilsTest, TestObjectValueToNPVariant) {
+ NPObjectPointer<NPObject> object =
+ NPCreateObject<StrictMock<MockNPObject> >(NULL);
+
+ ValueToNPVariant(object, &variant_);
+ EXPECT_TRUE(NPVARIANT_IS_OBJECT(variant_));
+ EXPECT_EQ(object.Get(), NPVARIANT_TO_OBJECT(variant_));
+
+ NPBrowser::get()->ReleaseVariantValue(&variant_);
+}
+
+TEST_F(NPUtilsTest, TestNullValueToNPVariant) {
+ ValueToNPVariant(NPObjectPointer<NPObject>(), &variant_);
+ EXPECT_TRUE(NPVARIANT_IS_NULL(variant_));
+}
+
+TEST_F(NPUtilsTest, CanCopyObjectSmartVariant) {
+ NPObjectPointer<NPObject> object =
+ NPCreateObject<StrictMock<MockNPObject> >(NULL);
+ EXPECT_EQ(1, object->referenceCount);
+ {
+ SmartNPVariant v1(object);
+ EXPECT_EQ(2, object->referenceCount);
+ {
+ SmartNPVariant v2(v1);
+ EXPECT_EQ(3, object->referenceCount);
+ }
+ EXPECT_EQ(2, object->referenceCount);
+ }
+ EXPECT_EQ(1, object->referenceCount);
+}
+
+TEST_F(NPUtilsTest, CanCopyStringSmartVariant) {
+ SmartNPVariant v1(std::string("hello"));
+ SmartNPVariant v2(v1);
+ std::string r;
+ EXPECT_TRUE(NPVariantToValue(&r, v2));
+ EXPECT_EQ(std::string("hello"), r);
+ EXPECT_NE(v1.value.stringValue.UTF8Characters,
+ v2.value.stringValue.UTF8Characters);
+}
+
+TEST_F(NPUtilsTest, CanReleaseSmartVariant) {
+ SmartNPVariant variant(std::string("hello"));
+ EXPECT_FALSE(variant.IsVoid());
+ variant.Release();
+ EXPECT_TRUE(variant.IsVoid());
+}
+
+template <typename T>
+class VariantMatcher : public testing::MatcherInterface<const NPVariant&> {
+ public:
+ explicit VariantMatcher(const T& value) : value_(value) {
+ }
+
+ virtual bool Matches(const NPVariant& variant) const {
+ T other_value;
+ return NPVariantToValue(&other_value, variant) && other_value == value_;
+ }
+
+ virtual void DescribeTo(::std::ostream* os) const {
+ *os << "equals " << value_;
+ }
+
+ virtual void DescribeNegationTo(::std::ostream* os) const {
+ *os << "does not equal " << value_;
+ }
+
+ private:
+ T value_;
+};
+
+template <typename T>
+Matcher<const NPVariant&> VariantMatches(const T& value) {
+ return MakeMatcher(new VariantMatcher<T>(value));
+}
+
+TEST_F(NPUtilsTest, CanDetermineIfObjectHasMethod) {
+ NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo");
+ NPObjectPointer<MockNPObject> object =
+ NPCreateObject<StrictMock<MockNPObject> >(NULL);
+
+ EXPECT_CALL(*object, HasMethod(name))
+ .WillOnce(Return(true));
+
+ EXPECT_TRUE(NPHasMethod(NULL, object, "foo"));
+}
+
+TEST_F(NPUtilsTest, CanInvokeVoidMethodWithNativeTypes) {
+ NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo");
+ NPObjectPointer<MockNPObject> object =
+ NPCreateObject<StrictMock<MockNPObject> >(NULL);
+
+ VOID_TO_NPVARIANT(variant_);
+
+ EXPECT_CALL(*object, Invoke(name, Pointee(VariantMatches<int32>(7)), 1, _))
+ .WillOnce(DoAll(SetArgumentPointee<3>(variant_),
+ Return(true)));
+
+ EXPECT_TRUE(NPInvokeVoid(NULL, object, "foo", 7));
+}
+
+TEST_F(NPUtilsTest, InvokeVoidMethodCanFail) {
+ NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo");
+ NPObjectPointer<MockNPObject> object =
+ NPCreateObject<StrictMock<MockNPObject> >(NULL);
+
+ VOID_TO_NPVARIANT(variant_);
+
+ EXPECT_CALL(*object, Invoke(name, Pointee(VariantMatches<int32>(7)), 1, _))
+ .WillOnce(DoAll(SetArgumentPointee<3>(variant_),
+ Return(false)));
+
+ EXPECT_FALSE(NPInvokeVoid(NULL, object, "foo", 7));
+}
+
+TEST_F(NPUtilsTest, CanInvokeNonVoidMethodWithNativeTypes) {
+ NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo");
+ NPObjectPointer<MockNPObject> object =
+ NPCreateObject<StrictMock<MockNPObject> >(NULL);
+
+ DOUBLE_TO_NPVARIANT(1.5, variant_);
+
+ EXPECT_CALL(*object, Invoke(name, Pointee(VariantMatches<int32>(7)), 1, _))
+ .WillOnce(DoAll(SetArgumentPointee<3>(variant_),
+ Return(true)));
+
+ double r;
+ EXPECT_TRUE(NPInvoke(NULL, object, "foo", 7, &r));
+ EXPECT_EQ(1.5, r);
+}
+
+TEST_F(NPUtilsTest, InvokeNonVoidMethodCanFail) {
+ NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo");
+ NPObjectPointer<MockNPObject> object =
+ NPCreateObject<StrictMock<MockNPObject> >(NULL);
+
+ DOUBLE_TO_NPVARIANT(1.5, variant_);
+
+ EXPECT_CALL(*object, Invoke(name, Pointee(VariantMatches<int32>(7)), 1, _))
+ .WillOnce(DoAll(SetArgumentPointee<3>(variant_),
+ Return(false)));
+
+ double r;
+ EXPECT_FALSE(NPInvoke(NULL, object, "foo", 7, &r));
+}
+
+TEST_F(NPUtilsTest, InvokeNonVoidMethodFailsIfResultIsIncompatible) {
+ NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo");
+ NPObjectPointer<MockNPObject> object =
+ NPCreateObject<StrictMock<MockNPObject> >(NULL);
+
+ DOUBLE_TO_NPVARIANT(1.5, variant_);
+
+ EXPECT_CALL(*object, Invoke(name, Pointee(VariantMatches<int32>(7)), 1, _))
+ .WillOnce(DoAll(SetArgumentPointee<3>(variant_),
+ Return(true)));
+
+ int r;
+ EXPECT_FALSE(NPInvoke(NULL, object, "foo", 7, &r));
+}
+
+TEST_F(NPUtilsTest, CanDetermineIfObjectHasProperty) {
+ NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo");
+ NPObjectPointer<MockNPObject> object =
+ NPCreateObject<StrictMock<MockNPObject> >(NULL);
+
+ EXPECT_CALL(*object, HasProperty(name))
+ .WillOnce(Return(true));
+
+ EXPECT_TRUE(NPHasProperty(NULL, object, "foo"));
+}
+
+TEST_F(NPUtilsTest, CanGetPropertyValue) {
+ NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo");
+ NPObjectPointer<MockNPObject> object =
+ NPCreateObject<StrictMock<MockNPObject> >(NULL);
+
+ DOUBLE_TO_NPVARIANT(1.5, variant_);
+
+ EXPECT_CALL(*object, GetProperty(name, _))
+ .WillOnce(DoAll(SetArgumentPointee<1>(variant_),
+ Return(true)));
+
+ double r;
+ EXPECT_TRUE(NPGetProperty(NULL, object, "foo", &r));
+}
+
+TEST_F(NPUtilsTest, NPGetPropertyReportsFailureIfResultTypeIsDifferent) {
+ NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo");
+ NPObjectPointer<MockNPObject> object =
+ NPCreateObject<StrictMock<MockNPObject> >(NULL);
+
+ DOUBLE_TO_NPVARIANT(1.5, variant_);
+
+ EXPECT_CALL(*object, GetProperty(name, _))
+ .WillOnce(DoAll(SetArgumentPointee<1>(variant_),
+ Return(true)));
+
+ bool r;
+ EXPECT_FALSE(NPGetProperty(NULL, object, "foo", &r));
+}
+
+TEST_F(NPUtilsTest, NPGetPropertyReportsFailureFromGetProperty) {
+ NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo");
+ NPObjectPointer<MockNPObject> object =
+ NPCreateObject<StrictMock<MockNPObject> >(NULL);
+
+ EXPECT_CALL(*object, GetProperty(name, _))
+ .WillOnce(Return(false));
+
+ double r;
+ EXPECT_FALSE(NPGetProperty(NULL, object, "foo", &r));
+}
+
+TEST_F(NPUtilsTest, CanSetPropertyValue) {
+ NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo");
+ NPObjectPointer<MockNPObject> object =
+ NPCreateObject<StrictMock<MockNPObject> >(NULL);
+
+ EXPECT_CALL(*object, SetProperty(name, Pointee(VariantMatches(1.5))))
+ .WillOnce(Return(true));
+
+ EXPECT_TRUE(NPSetProperty(NULL, object, "foo", 1.5));
+}
+
+TEST_F(NPUtilsTest, NPSetPropertyReportsFailureFromSetProperty) {
+ NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo");
+ NPObjectPointer<MockNPObject> object =
+ NPCreateObject<StrictMock<MockNPObject> >(NULL);
+
+ EXPECT_CALL(*object, SetProperty(name, Pointee(VariantMatches(1.5))))
+ .WillOnce(Return(false));
+
+ EXPECT_FALSE(NPSetProperty(NULL, object, "foo", 1.5));
+}
+
+TEST_F(NPUtilsTest, CanRemovePropertyValue) {
+ NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo");
+ NPObjectPointer<MockNPObject> object =
+ NPCreateObject<StrictMock<MockNPObject> >(NULL);
+
+ EXPECT_CALL(*object, RemoveProperty(name))
+ .WillOnce(Return(true));
+
+ EXPECT_TRUE(NPRemoveProperty(NULL, object, "foo"));
+}
+
+} // namespace np_utils
diff --git a/gpu/np_utils/webkit_browser.h b/gpu/np_utils/webkit_browser.h
new file mode 100644
index 0000000..6b57d05
--- /dev/null
+++ b/gpu/np_utils/webkit_browser.h
@@ -0,0 +1,117 @@
+// Copyright (c) 2006-2008 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.
+
+#ifndef GPU_NP_UTILS_WEBKIT_BROWSER_H_
+#define GPU_NP_UTILS_WEBKIT_BROWSER_H_
+
+// TODO(apatrick): This does not belong in np_utils. np_utils should not be
+// dependent on WebKit (and it isn't - that's why the member functions are
+// inline).
+
+#include <stdlib.h>
+
+#include "gpu/np_utils/np_browser.h"
+#include "WebKit/api/public/WebBindings.h"
+
+typedef struct _NPNetscapeFuncs NPNetscapeFuncs;
+typedef struct _NPChromiumFuncs NPChromiumFuncs;
+
+namespace np_utils {
+
+// This class implements NPBrowser for the WebKit WebBindings.
+class WebKitBrowser : public NPBrowser {
+ public:
+ WebKitBrowser(): NPBrowser(NULL) {
+ }
+
+ // Standard functions from NPNetscapeFuncs.
+
+ virtual NPIdentifier GetStringIdentifier(const NPUTF8* name) {
+ return WebKit::WebBindings::getStringIdentifier(name);
+ }
+
+ virtual void* MemAlloc(size_t size) {
+ return malloc(size);
+ }
+
+ virtual void MemFree(void* p) {
+ free(p);
+ }
+
+ virtual NPObject* CreateObject(NPP npp, const NPClass* cl) {
+ return WebKit::WebBindings::createObject(npp, const_cast<NPClass*>(cl));
+ }
+
+ virtual NPObject* RetainObject(NPObject* object) {
+ return WebKit::WebBindings::retainObject(object);
+ }
+
+ virtual void ReleaseObject(NPObject* object) {
+ WebKit::WebBindings::releaseObject(object);
+ }
+
+ virtual void ReleaseVariantValue(NPVariant* variant) {
+ WebKit::WebBindings::releaseVariantValue(variant);
+ }
+
+ virtual bool HasProperty(NPP npp,
+ NPObject* object,
+ NPIdentifier name) {
+ return WebKit::WebBindings::hasProperty(npp, object, name);
+ }
+
+ virtual bool GetProperty(NPP npp,
+ NPObject* object,
+ NPIdentifier name,
+ NPVariant* result) {
+ return WebKit::WebBindings::getProperty(npp, object, name, result);
+ }
+
+ virtual bool SetProperty(NPP npp,
+ NPObject* object,
+ NPIdentifier name,
+ const NPVariant* result) {
+ return WebKit::WebBindings::setProperty(npp, object, name, result);
+ }
+
+ virtual bool RemoveProperty(NPP npp,
+ NPObject* object,
+ NPIdentifier name) {
+ return WebKit::WebBindings::removeProperty(npp, object, name);
+ }
+
+ virtual bool HasMethod(NPP npp,
+ NPObject* object,
+ NPIdentifier name) {
+ return WebKit::WebBindings::hasMethod(npp, object, name);
+ }
+
+ virtual bool Invoke(NPP npp,
+ NPObject* object,
+ NPIdentifier name,
+ const NPVariant* args,
+ uint32_t num_args,
+ NPVariant* result) {
+ return WebKit::WebBindings::invoke(npp, object, name, args, num_args,
+ result);
+ }
+
+ virtual NPObject* GetWindowNPObject(NPP npp) {
+ NPObject* window;
+ if (NPERR_NO_ERROR == NPN_GetValue(npp,
+ NPNVWindowNPObject,
+ &window)) {
+ return window;
+ } else {
+ return NULL;
+ }
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(WebKitBrowser);
+};
+
+} // namespace np_utils
+
+#endif // GPU_NP_UTILS_WEBKIT_BROWSER_H_