Home | History | Annotate | Download | only in plugin
      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:
    148     Register(const std::string& identifier) {
    149       registerCreateTestFunction(identifier, Register::create);
    150     }
    151 
    152    private:
    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 
    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:
    176     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.
    185     bool hasMethod(NPIdentifier methodName) {
    186       assert(false);
    187       return false;
    188     }
    189 
    190     bool invoke(NPIdentifier methodName,
    191                 const NPVariant*,
    192                 uint32_t,
    193                 NPVariant* result) {
    194       assert(false);
    195       return false;
    196     }
    197 
    198     bool invokeDefault(const NPVariant*, uint32_t, NPVariant* result) {
    199       assert(false);
    200       return false;
    201     }
    202 
    203     bool hasProperty(NPIdentifier propertyName) {
    204       assert(false);
    205       return false;
    206     }
    207 
    208     bool getProperty(NPIdentifier propertyName, NPVariant* result) {
    209       assert(false);
    210       return false;
    211     }
    212 
    213     bool removeProperty(NPIdentifier propertyName) {
    214       assert(false);
    215       return false;
    216     }
    217 
    218     // Helper functions.
    219     bool identifierIs(NPIdentifier identifier, const char* value) {
    220       return pluginTest()->NPN_GetStringIdentifier(value) == identifier;
    221     }
    222 
    223    protected:
    224     Object() : m_pluginTest(0) {}
    225 
    226     virtual ~Object() {}
    227 
    228     PluginTest* pluginTest() const { return m_pluginTest; }
    229 
    230    private:
    231     static NPObject* NP_Allocate(NPP npp, NPClass* aClass) { return new T; }
    232 
    233     static void NP_Deallocate(NPObject* npObject) {
    234       delete static_cast<T*>(npObject);
    235     }
    236 
    237     static bool NP_HasMethod(NPObject* npObject, NPIdentifier methodName) {
    238       return static_cast<T*>(npObject)->hasMethod(methodName);
    239     }
    240 
    241     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 
    250     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 
    258     static bool NP_HasProperty(NPObject* npObject, NPIdentifier propertyName) {
    259       return static_cast<T*>(npObject)->hasProperty(propertyName);
    260     }
    261 
    262     static bool NP_GetProperty(NPObject* npObject,
    263                                NPIdentifier propertyName,
    264                                NPVariant* result) {
    265       return static_cast<T*>(npObject)->getProperty(propertyName, result);
    266     }
    267 
    268     static bool NP_RemoveProperty(NPObject* npObject,
    269                                   NPIdentifier propertyName) {
    270       return static_cast<T*>(npObject)->removeProperty(propertyName);
    271     }
    272 
    273     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