| // Copyright 2014 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. |
| |
| /* |
| * Copyright (C) 2010 Apple Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
| * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
| * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
| * THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #ifndef PluginTest_h |
| #define PluginTest_h |
| |
| #include <assert.h> |
| #include <bindings/npfunctions.h> |
| #include <stdint.h> |
| |
| #include <map> |
| #include <string> |
| |
| // Helper classes for implementing has_member |
| typedef char (&no_tag)[1]; |
| typedef char (&yes_tag)[2]; |
| |
| #define DEFINE_HAS_MEMBER_CHECK(member, returnType, argumentTypes) \ |
| template <typename T, returnType(T::*member) argumentTypes> \ |
| struct pmf_##member##_helper {}; \ |
| template <typename T> \ |
| no_tag has_member_##member##_helper(...); \ |
| template <typename T> \ |
| yes_tag has_member_##member##_helper(pmf_##member##_helper<T, &T::member>*); \ |
| template <typename T> \ |
| struct has_member_##member { \ |
| static const bool value = \ |
| sizeof(has_member_##member##_helper<T>(0)) == sizeof(yes_tag); \ |
| }; |
| |
| DEFINE_HAS_MEMBER_CHECK(hasMethod, bool, (NPIdentifier methodName)); |
| DEFINE_HAS_MEMBER_CHECK( |
| invoke, |
| bool, |
| (NPIdentifier methodName, const NPVariant*, uint32_t, NPVariant* result)); |
| DEFINE_HAS_MEMBER_CHECK(invokeDefault, |
| bool, |
| (const NPVariant*, uint32_t, NPVariant* result)); |
| DEFINE_HAS_MEMBER_CHECK(hasProperty, bool, (NPIdentifier propertyName)); |
| DEFINE_HAS_MEMBER_CHECK(getProperty, |
| bool, |
| (NPIdentifier propertyName, NPVariant* result)); |
| DEFINE_HAS_MEMBER_CHECK(removeProperty, bool, (NPIdentifier propertyName)); |
| |
| class PluginTest { |
| public: |
| static PluginTest* create(NPP, const std::string& identifier); |
| virtual ~PluginTest(); |
| |
| static void NP_Shutdown(); |
| |
| // NPP functions. |
| virtual NPError NPP_New(NPMIMEType pluginType, |
| uint16_t mode, |
| int16_t argc, |
| char* argn[], |
| char* argv[], |
| NPSavedData* saved); |
| virtual NPError NPP_Destroy(NPSavedData**); |
| virtual NPError NPP_SetWindow(NPWindow*); |
| virtual NPError NPP_NewStream(NPMIMEType, |
| NPStream*, |
| NPBool seekable, |
| uint16_t* stype); |
| virtual NPError NPP_DestroyStream(NPStream*, NPReason); |
| virtual int32_t NPP_WriteReady(NPStream*); |
| virtual int32_t NPP_Write(NPStream*, |
| int32_t offset, |
| int32_t len, |
| void* buffer); |
| virtual int16_t NPP_HandleEvent(void* event); |
| virtual bool NPP_URLNotify(const char* url, NPReason, void* notifyData); |
| virtual NPError NPP_GetValue(NPPVariable, void* value); |
| virtual NPError NPP_SetValue(NPNVariable, void* value); |
| |
| // NPN functions. |
| NPError NPN_GetValue(NPNVariable, void* value); |
| void NPN_InvalidateRect(NPRect* invalidRect); |
| bool NPN_Invoke(NPObject*, |
| NPIdentifier methodName, |
| const NPVariant* args, |
| uint32_t argCount, |
| NPVariant* result); |
| void* NPN_MemAlloc(uint32_t size); |
| |
| // NPRuntime NPN functions. |
| NPIdentifier NPN_GetStringIdentifier(const NPUTF8* name); |
| NPIdentifier NPN_GetIntIdentifier(int32_t intid); |
| bool NPN_IdentifierIsString(NPIdentifier); |
| NPUTF8* NPN_UTF8FromIdentifier(NPIdentifier); |
| int32_t NPN_IntFromIdentifier(NPIdentifier); |
| |
| NPObject* NPN_CreateObject(NPClass*); |
| NPObject* NPN_RetainObject(NPObject*); |
| void NPN_ReleaseObject(NPObject*); |
| bool NPN_GetProperty(NPObject*, NPIdentifier propertyName, NPVariant* value); |
| bool NPN_RemoveProperty(NPObject*, NPIdentifier propertyName); |
| void NPN_ReleaseVariantValue(NPVariant*); |
| |
| #ifdef XP_MACOSX |
| bool NPN_ConvertPoint(double sourceX, |
| double sourceY, |
| NPCoordinateSpace sourceSpace, |
| double* destX, |
| double* destY, |
| NPCoordinateSpace destSpace); |
| #endif |
| |
| bool executeScript(const NPString*, NPVariant* result); |
| void executeScript(const char*); |
| void log(const char* format, ...); |
| |
| void registerNPShutdownFunction(void (*)()); |
| |
| static void indicateTestFailure(); |
| |
| template <typename TestClassTy> |
| class Register { |
| public: |
| Register(const std::string& identifier) { |
| registerCreateTestFunction(identifier, Register::create); |
| } |
| |
| private: |
| static PluginTest* create(NPP npp, const std::string& identifier) { |
| return new TestClassTy(npp, identifier); |
| } |
| }; |
| |
| protected: |
| PluginTest(NPP npp, const std::string& identifier); |
| |
| // FIXME: A plugin test shouldn't need to know about it's NPP. Make this |
| // private. |
| NPP m_npp; |
| |
| const std::string& identifier() const { return m_identifier; } |
| |
| static NPNetscapeFuncs* netscapeFuncs(); |
| |
| void waitUntilDone(); |
| void notifyDone(); |
| |
| // NPObject helper template. |
| template <typename T> |
| struct Object : NPObject { |
| public: |
| static NPObject* create(PluginTest* pluginTest) { |
| Object* object = |
| static_cast<Object*>(pluginTest->NPN_CreateObject(npClass())); |
| |
| object->m_pluginTest = pluginTest; |
| return object; |
| } |
| |
| // These should never be called. |
| bool hasMethod(NPIdentifier methodName) { |
| assert(false); |
| return false; |
| } |
| |
| bool invoke(NPIdentifier methodName, |
| const NPVariant*, |
| uint32_t, |
| NPVariant* result) { |
| assert(false); |
| return false; |
| } |
| |
| bool invokeDefault(const NPVariant*, uint32_t, NPVariant* result) { |
| assert(false); |
| return false; |
| } |
| |
| bool hasProperty(NPIdentifier propertyName) { |
| assert(false); |
| return false; |
| } |
| |
| bool getProperty(NPIdentifier propertyName, NPVariant* result) { |
| assert(false); |
| return false; |
| } |
| |
| bool removeProperty(NPIdentifier propertyName) { |
| assert(false); |
| return false; |
| } |
| |
| // Helper functions. |
| bool identifierIs(NPIdentifier identifier, const char* value) { |
| return pluginTest()->NPN_GetStringIdentifier(value) == identifier; |
| } |
| |
| protected: |
| Object() : m_pluginTest(0) {} |
| |
| virtual ~Object() {} |
| |
| PluginTest* pluginTest() const { return m_pluginTest; } |
| |
| private: |
| static NPObject* NP_Allocate(NPP npp, NPClass* aClass) { return new T; } |
| |
| static void NP_Deallocate(NPObject* npObject) { |
| delete static_cast<T*>(npObject); |
| } |
| |
| static bool NP_HasMethod(NPObject* npObject, NPIdentifier methodName) { |
| return static_cast<T*>(npObject)->hasMethod(methodName); |
| } |
| |
| static bool NP_Invoke(NPObject* npObject, |
| NPIdentifier methodName, |
| const NPVariant* arguments, |
| uint32_t argumentCount, |
| NPVariant* result) { |
| return static_cast<T*>(npObject) |
| ->invoke(methodName, arguments, argumentCount, result); |
| } |
| |
| static bool NP_InvokeDefault(NPObject* npObject, |
| const NPVariant* arguments, |
| uint32_t argumentCount, |
| NPVariant* result) { |
| return static_cast<T*>(npObject) |
| ->invokeDefault(arguments, argumentCount, result); |
| } |
| |
| static bool NP_HasProperty(NPObject* npObject, NPIdentifier propertyName) { |
| return static_cast<T*>(npObject)->hasProperty(propertyName); |
| } |
| |
| static bool NP_GetProperty(NPObject* npObject, |
| NPIdentifier propertyName, |
| NPVariant* result) { |
| return static_cast<T*>(npObject)->getProperty(propertyName, result); |
| } |
| |
| static bool NP_RemoveProperty(NPObject* npObject, |
| NPIdentifier propertyName) { |
| return static_cast<T*>(npObject)->removeProperty(propertyName); |
| } |
| |
| static NPClass* npClass() { |
| static NPClass npClass = { |
| NP_CLASS_STRUCT_VERSION, NP_Allocate, NP_Deallocate, |
| 0, // NPClass::invalidate |
| has_member_hasMethod<T>::value ? NP_HasMethod : 0, |
| has_member_invoke<T>::value ? NP_Invoke : 0, |
| has_member_invokeDefault<T>::value ? NP_InvokeDefault : 0, |
| has_member_hasProperty<T>::value ? NP_HasProperty : 0, |
| has_member_getProperty<T>::value ? NP_GetProperty : 0, |
| 0, // NPClass::setProperty |
| has_member_removeProperty<T>::value ? NP_RemoveProperty : 0, |
| 0, // NPClass::enumerate |
| 0 // NPClass::construct |
| }; |
| |
| return &npClass; |
| }; |
| |
| PluginTest* m_pluginTest; |
| }; |
| |
| private: |
| typedef PluginTest* (*CreateTestFunction)(NPP, const std::string&); |
| |
| static void registerCreateTestFunction(const std::string&, |
| CreateTestFunction); |
| static std::map<std::string, CreateTestFunction>& createTestFunctions(); |
| |
| std::string m_identifier; |
| }; |
| |
| #endif // PluginTest_h |