1 /* 2 * Copyright (C) 2010 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #ifndef PluginTest_h 27 #define PluginTest_h 28 29 #include <WebKit/npfunctions.h> 30 #include <assert.h> 31 #include <map> 32 #include <string> 33 34 // Helper classes for implementing has_member 35 typedef char (&no_tag)[1]; 36 typedef char (&yes_tag)[2]; 37 38 #define DEFINE_HAS_MEMBER_CHECK(member, returnType, argumentTypes) \ 39 template<typename T, returnType (T::*member) argumentTypes> struct pmf_##member##_helper {}; \ 40 template<typename T> no_tag has_member_##member##_helper(...); \ 41 template<typename T> yes_tag has_member_##member##_helper(pmf_##member##_helper<T, &T::member >*); \ 42 template<typename T> struct has_member_##member { \ 43 static const bool value = sizeof(has_member_##member##_helper<T>(0)) == sizeof(yes_tag); \ 44 }; 45 46 DEFINE_HAS_MEMBER_CHECK(hasMethod, bool, (NPIdentifier methodName)); 47 DEFINE_HAS_MEMBER_CHECK(invoke, bool, (NPIdentifier methodName, const NPVariant*, uint32_t, NPVariant* result)); 48 DEFINE_HAS_MEMBER_CHECK(invokeDefault, bool, (const NPVariant*, uint32_t, NPVariant* result)); 49 DEFINE_HAS_MEMBER_CHECK(hasProperty, bool, (NPIdentifier propertyName)); 50 DEFINE_HAS_MEMBER_CHECK(getProperty, bool, (NPIdentifier propertyName, NPVariant* result)); 51 52 class PluginTest { 53 public: 54 static PluginTest* create(NPP, const std::string& identifier); 55 virtual ~PluginTest(); 56 57 static void NP_Shutdown(); 58 59 // NPP functions. 60 virtual NPError NPP_New(NPMIMEType pluginType, uint16_t mode, int16_t argc, char *argn[], char *argv[], NPSavedData *saved); 61 virtual NPError NPP_Destroy(NPSavedData**); 62 virtual NPError NPP_DestroyStream(NPStream* stream, NPReason reason); 63 virtual NPError NPP_GetValue(NPPVariable, void* value); 64 virtual NPError NPP_SetWindow(NPP, NPWindow*); 65 virtual int16_t NPP_HandleEvent(void* event); 66 67 // NPN functions. 68 NPError NPN_GetURL(const char* url, const char* target); 69 70 void NPN_InvalidateRect(NPRect* invalidRect); 71 NPIdentifier NPN_GetStringIdentifier(const NPUTF8* name); 72 NPIdentifier NPN_GetIntIdentifier(int32_t intid); 73 NPError NPN_GetValue(NPNVariable, void* value); 74 NPObject* NPN_CreateObject(NPClass*); 75 bool NPN_RemoveProperty(NPObject*, NPIdentifier propertyName); 76 #ifdef XP_MACOSX 77 bool NPN_ConvertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace); 78 #endif 79 80 void executeScript(const char*); 81 void log(const char* format, ...); 82 83 void registerNPShutdownFunction(void (*)()); 84 85 static void indicateTestFailure(); 86 87 template<typename TestClassTy> class Register { 88 public: 89 Register(const std::string& identifier) 90 { 91 registerCreateTestFunction(identifier, Register::create); 92 } 93 94 private: 95 static PluginTest* create(NPP npp, const std::string& identifier) 96 { 97 return new TestClassTy(npp, identifier); 98 } 99 }; 100 101 protected: 102 PluginTest(NPP npp, const std::string& identifier); 103 104 // FIXME: A plug-in test shouldn't need to know about it's NPP. Make this private. 105 NPP m_npp; 106 107 const std::string& identifier() const { return m_identifier; } 108 109 void waitUntilDone(); 110 void notifyDone(); 111 112 // NPObject helper template. 113 template<typename T> struct Object : NPObject { 114 public: 115 static NPObject* create(PluginTest* pluginTest) 116 { 117 Object* object = static_cast<Object*>(pluginTest->NPN_CreateObject(npClass())); 118 119 object->m_pluginTest = pluginTest; 120 return object; 121 } 122 123 // These should never be called. 124 bool hasMethod(NPIdentifier methodName) 125 { 126 assert(false); 127 return false; 128 } 129 130 bool invoke(NPIdentifier methodName, const NPVariant*, uint32_t, NPVariant* result) 131 { 132 assert(false); 133 return false; 134 } 135 136 bool invokeDefault(const NPVariant*, uint32_t, NPVariant* result) 137 { 138 assert(false); 139 return false; 140 } 141 142 bool hasProperty(NPIdentifier propertyName) 143 { 144 assert(false); 145 return false; 146 } 147 148 bool getProperty(NPIdentifier propertyName, NPVariant* result) 149 { 150 assert(false); 151 return false; 152 } 153 154 protected: 155 Object() 156 : m_pluginTest(0) 157 { 158 } 159 160 virtual ~Object() 161 { 162 } 163 164 PluginTest* pluginTest() const { return m_pluginTest; } 165 166 private: 167 static NPObject* NP_Allocate(NPP npp, NPClass* aClass) 168 { 169 return new T; 170 } 171 172 static void NP_Deallocate(NPObject* npObject) 173 { 174 delete static_cast<T*>(npObject); 175 } 176 177 static bool NP_HasMethod(NPObject* npObject, NPIdentifier methodName) 178 { 179 return static_cast<T*>(npObject)->hasMethod(methodName); 180 } 181 182 static bool NP_Invoke(NPObject* npObject, NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result) 183 { 184 return static_cast<T*>(npObject)->invoke(methodName, arguments, argumentCount, result); 185 } 186 187 static bool NP_InvokeDefault(NPObject* npObject, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result) 188 { 189 return static_cast<T*>(npObject)->invokeDefault(arguments, argumentCount, result); 190 } 191 192 static bool NP_HasProperty(NPObject* npObject, NPIdentifier propertyName) 193 { 194 return static_cast<T*>(npObject)->hasProperty(propertyName); 195 } 196 197 static bool NP_GetProperty(NPObject* npObject, NPIdentifier propertyName, NPVariant* result) 198 { 199 return static_cast<T*>(npObject)->getProperty(propertyName, result); 200 } 201 202 static NPClass* npClass() 203 { 204 static NPClass npClass = { 205 NP_CLASS_STRUCT_VERSION, 206 NP_Allocate, 207 NP_Deallocate, 208 0, // NPClass::invalidate 209 has_member_hasMethod<T>::value ? NP_HasMethod : 0, 210 has_member_invoke<T>::value ? NP_Invoke : 0, 211 has_member_invokeDefault<T>::value ? NP_InvokeDefault : 0, 212 has_member_hasProperty<T>::value ? NP_HasProperty : 0, 213 has_member_getProperty<T>::value ? NP_GetProperty : 0, 214 0, // NPClass::setProperty 215 0, // NPClass::removeProperty 216 0, // NPClass::enumerate 217 0 // NPClass::construct 218 }; 219 220 return &npClass; 221 }; 222 223 PluginTest* m_pluginTest; 224 }; 225 226 private: 227 typedef PluginTest* (*CreateTestFunction)(NPP, const std::string&); 228 229 static void registerCreateTestFunction(const std::string&, CreateTestFunction); 230 static std::map<std::string, CreateTestFunction>& createTestFunctions(); 231 232 std::string m_identifier; 233 }; 234 235 #endif // PluginTest_h 236