1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 /* 6 * Copyright (C) 2010 Apple Inc. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 19 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 * THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #ifndef PluginTest_h 31 #define PluginTest_h 32 33 #include <assert.h> 34 #include <bindings/npfunctions.h> 35 #include <map> 36 #include <string> 37 38 // Helper classes for implementing has_member 39 typedef char (&no_tag)[1]; 40 typedef char (&yes_tag)[2]; 41 42 #define DEFINE_HAS_MEMBER_CHECK(member, returnType, argumentTypes) \ 43 template <typename T, returnType(T::*member) argumentTypes> \ 44 struct pmf_##member##_helper {}; \ 45 template <typename T> \ 46 no_tag has_member_##member##_helper(...); \ 47 template <typename T> \ 48 yes_tag has_member_##member##_helper(pmf_##member##_helper<T, &T::member>*); \ 49 template <typename T> \ 50 struct has_member_##member { \ 51 static const bool value = \ 52 sizeof(has_member_##member##_helper<T>(0)) == sizeof(yes_tag); \ 53 }; 54 55 DEFINE_HAS_MEMBER_CHECK(hasMethod, bool, (NPIdentifier methodName)); 56 DEFINE_HAS_MEMBER_CHECK( 57 invoke, 58 bool, 59 (NPIdentifier methodName, const NPVariant*, uint32_t, NPVariant* result)); 60 DEFINE_HAS_MEMBER_CHECK(invokeDefault, 61 bool, 62 (const NPVariant*, uint32_t, NPVariant* result)); 63 DEFINE_HAS_MEMBER_CHECK(hasProperty, bool, (NPIdentifier propertyName)); 64 DEFINE_HAS_MEMBER_CHECK(getProperty, 65 bool, 66 (NPIdentifier propertyName, NPVariant* result)); 67 DEFINE_HAS_MEMBER_CHECK(removeProperty, bool, (NPIdentifier propertyName)); 68 69 class PluginTest { 70 public: 71 static PluginTest* create(NPP, const std::string& identifier); 72 virtual ~PluginTest(); 73 74 static void NP_Shutdown(); 75 76 // NPP functions. 77 virtual NPError NPP_New(NPMIMEType pluginType, 78 uint16_t mode, 79 int16_t argc, 80 char* argn[], 81 char* argv[], 82 NPSavedData* saved); 83 virtual NPError NPP_Destroy(NPSavedData**); 84 virtual NPError NPP_SetWindow(NPWindow*); 85 virtual NPError NPP_NewStream(NPMIMEType, 86 NPStream*, 87 NPBool seekable, 88 uint16_t* stype); 89 virtual NPError NPP_DestroyStream(NPStream*, NPReason); 90 virtual int32_t NPP_WriteReady(NPStream*); 91 virtual int32_t NPP_Write(NPStream*, 92 int32_t offset, 93 int32_t len, 94 void* buffer); 95 virtual int16_t NPP_HandleEvent(void* event); 96 virtual bool NPP_URLNotify(const char* url, NPReason, void* notifyData); 97 virtual NPError NPP_GetValue(NPPVariable, void* value); 98 virtual NPError NPP_SetValue(NPNVariable, void* value); 99 100 // NPN functions. 101 NPError NPN_GetURL(const char* url, const char* target); 102 NPError NPN_GetURLNotify(const char* url, 103 const char* target, 104 void* notifyData); 105 NPError NPN_GetValue(NPNVariable, void* value); 106 void NPN_InvalidateRect(NPRect* invalidRect); 107 bool NPN_Invoke(NPObject*, 108 NPIdentifier methodName, 109 const NPVariant* args, 110 uint32_t argCount, 111 NPVariant* result); 112 void* NPN_MemAlloc(uint32_t size); 113 114 // NPRuntime NPN functions. 115 NPIdentifier NPN_GetStringIdentifier(const NPUTF8* name); 116 NPIdentifier NPN_GetIntIdentifier(int32_t intid); 117 bool NPN_IdentifierIsString(NPIdentifier); 118 NPUTF8* NPN_UTF8FromIdentifier(NPIdentifier); 119 int32_t NPN_IntFromIdentifier(NPIdentifier); 120 121 NPObject* NPN_CreateObject(NPClass*); 122 NPObject* NPN_RetainObject(NPObject*); 123 void NPN_ReleaseObject(NPObject*); 124 bool NPN_GetProperty(NPObject*, NPIdentifier propertyName, NPVariant* value); 125 bool NPN_RemoveProperty(NPObject*, NPIdentifier propertyName); 126 void NPN_ReleaseVariantValue(NPVariant*); 127 128 #ifdef XP_MACOSX 129 bool NPN_ConvertPoint(double sourceX, 130 double sourceY, 131 NPCoordinateSpace sourceSpace, 132 double* destX, 133 double* destY, 134 NPCoordinateSpace destSpace); 135 #endif 136 137 bool executeScript(const NPString*, NPVariant* result); 138 void executeScript(const char*); 139 void log(const char* format, ...); 140 141 void registerNPShutdownFunction(void (*)()); 142 143 static void indicateTestFailure(); 144 145 template <typename TestClassTy> 146 class Register { 147 public: Register(const std::string & identifier)148 Register(const std::string& identifier) { 149 registerCreateTestFunction(identifier, Register::create); 150 } 151 152 private: create(NPP npp,const std::string & identifier)153 static PluginTest* create(NPP npp, const std::string& identifier) { 154 return new TestClassTy(npp, identifier); 155 } 156 }; 157 158 protected: 159 PluginTest(NPP npp, const std::string& identifier); 160 161 // FIXME: A plug-in test shouldn't need to know about it's NPP. Make this 162 // private. 163 NPP m_npp; 164 identifier()165 const std::string& identifier() const { return m_identifier; } 166 167 static NPNetscapeFuncs* netscapeFuncs(); 168 169 void waitUntilDone(); 170 void notifyDone(); 171 172 // NPObject helper template. 173 template <typename T> 174 struct Object : NPObject { 175 public: createObject176 static NPObject* create(PluginTest* pluginTest) { 177 Object* object = 178 static_cast<Object*>(pluginTest->NPN_CreateObject(npClass())); 179 180 object->m_pluginTest = pluginTest; 181 return object; 182 } 183 184 // These should never be called. hasMethodObject185 bool hasMethod(NPIdentifier methodName) { 186 assert(false); 187 return false; 188 } 189 invokeObject190 bool invoke(NPIdentifier methodName, 191 const NPVariant*, 192 uint32_t, 193 NPVariant* result) { 194 assert(false); 195 return false; 196 } 197 invokeDefaultObject198 bool invokeDefault(const NPVariant*, uint32_t, NPVariant* result) { 199 assert(false); 200 return false; 201 } 202 hasPropertyObject203 bool hasProperty(NPIdentifier propertyName) { 204 assert(false); 205 return false; 206 } 207 getPropertyObject208 bool getProperty(NPIdentifier propertyName, NPVariant* result) { 209 assert(false); 210 return false; 211 } 212 removePropertyObject213 bool removeProperty(NPIdentifier propertyName) { 214 assert(false); 215 return false; 216 } 217 218 // Helper functions. identifierIsObject219 bool identifierIs(NPIdentifier identifier, const char* value) { 220 return pluginTest()->NPN_GetStringIdentifier(value) == identifier; 221 } 222 223 protected: ObjectObject224 Object() : m_pluginTest(0) {} 225 ~ObjectObject226 virtual ~Object() {} 227 pluginTestObject228 PluginTest* pluginTest() const { return m_pluginTest; } 229 230 private: NP_AllocateObject231 static NPObject* NP_Allocate(NPP npp, NPClass* aClass) { return new T; } 232 NP_DeallocateObject233 static void NP_Deallocate(NPObject* npObject) { 234 delete static_cast<T*>(npObject); 235 } 236 NP_HasMethodObject237 static bool NP_HasMethod(NPObject* npObject, NPIdentifier methodName) { 238 return static_cast<T*>(npObject)->hasMethod(methodName); 239 } 240 NP_InvokeObject241 static bool NP_Invoke(NPObject* npObject, 242 NPIdentifier methodName, 243 const NPVariant* arguments, 244 uint32_t argumentCount, 245 NPVariant* result) { 246 return static_cast<T*>(npObject) 247 ->invoke(methodName, arguments, argumentCount, result); 248 } 249 NP_InvokeDefaultObject250 static bool NP_InvokeDefault(NPObject* npObject, 251 const NPVariant* arguments, 252 uint32_t argumentCount, 253 NPVariant* result) { 254 return static_cast<T*>(npObject) 255 ->invokeDefault(arguments, argumentCount, result); 256 } 257 NP_HasPropertyObject258 static bool NP_HasProperty(NPObject* npObject, NPIdentifier propertyName) { 259 return static_cast<T*>(npObject)->hasProperty(propertyName); 260 } 261 NP_GetPropertyObject262 static bool NP_GetProperty(NPObject* npObject, 263 NPIdentifier propertyName, 264 NPVariant* result) { 265 return static_cast<T*>(npObject)->getProperty(propertyName, result); 266 } 267 NP_RemovePropertyObject268 static bool NP_RemoveProperty(NPObject* npObject, 269 NPIdentifier propertyName) { 270 return static_cast<T*>(npObject)->removeProperty(propertyName); 271 } 272 npClassObject273 static NPClass* npClass() { 274 static NPClass npClass = { 275 NP_CLASS_STRUCT_VERSION, NP_Allocate, NP_Deallocate, 276 0, // NPClass::invalidate 277 has_member_hasMethod<T>::value ? NP_HasMethod : 0, 278 has_member_invoke<T>::value ? NP_Invoke : 0, 279 has_member_invokeDefault<T>::value ? NP_InvokeDefault : 0, 280 has_member_hasProperty<T>::value ? NP_HasProperty : 0, 281 has_member_getProperty<T>::value ? NP_GetProperty : 0, 282 0, // NPClass::setProperty 283 has_member_removeProperty<T>::value ? NP_RemoveProperty : 0, 284 0, // NPClass::enumerate 285 0 // NPClass::construct 286 }; 287 288 return &npClass; 289 }; 290 291 PluginTest* m_pluginTest; 292 }; 293 294 private: 295 typedef PluginTest* (*CreateTestFunction)(NPP, const std::string&); 296 297 static void registerCreateTestFunction(const std::string&, 298 CreateTestFunction); 299 static std::map<std::string, CreateTestFunction>& createTestFunctions(); 300 301 std::string m_identifier; 302 }; 303 304 #endif // PluginTest_h 305