blob: 9873d83f9ca02c6225d66377621df541a21febcf [file] [log] [blame]
// 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