dom/plugins/ipc/PluginScriptableObjectUtils.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     2  * vim: sw=2 ts=2 et :
     3  * This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #ifndef dom_plugins_PluginScriptableObjectUtils_h
     8 #define dom_plugins_PluginScriptableObjectUtils_h
    10 #include "PluginModuleParent.h"
    11 #include "PluginModuleChild.h"
    12 #include "PluginInstanceParent.h"
    13 #include "PluginInstanceChild.h"
    14 #include "PluginScriptableObjectParent.h"
    15 #include "PluginScriptableObjectChild.h"
    17 #include "npapi.h"
    18 #include "npfunctions.h"
    19 #include "npruntime.h"
    21 #include "nsDebug.h"
    23 namespace mozilla {
    24 namespace plugins {
    26 inline PluginInstanceParent*
    27 GetInstance(NPObject* aObject)
    28 {
    29   NS_ASSERTION(aObject->_class == PluginScriptableObjectParent::GetClass(),
    30                "Bad class!");
    32   ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
    33   if (object->invalidated) {
    34     NS_WARNING("Calling method on an invalidated object!");
    35     return nullptr;
    36   }
    37   if (!object->parent) {
    38     return nullptr;
    39   }
    40   return object->parent->GetInstance();
    41 }
    43 inline NPObject*
    44 NPObjectFromVariant(const Variant& aRemoteVariant)
    45 {
    46   switch (aRemoteVariant.type()) {
    47     case Variant::TPPluginScriptableObjectParent: {
    48       PluginScriptableObjectParent* actor =
    49         const_cast<PluginScriptableObjectParent*>(
    50           reinterpret_cast<const PluginScriptableObjectParent*>(
    51             aRemoteVariant.get_PPluginScriptableObjectParent()));
    52       return actor->GetObject(true);
    53     }
    55     case Variant::TPPluginScriptableObjectChild: {
    56       PluginScriptableObjectChild* actor =
    57         const_cast<PluginScriptableObjectChild*>(
    58           reinterpret_cast<const PluginScriptableObjectChild*>(
    59             aRemoteVariant.get_PPluginScriptableObjectChild()));
    60       return actor->GetObject(true);
    61     }
    63     default:
    64       NS_NOTREACHED("Shouldn't get here!");
    65       return nullptr;
    66   }
    67 }
    69 inline NPObject*
    70 NPObjectFromVariant(const NPVariant& aVariant)
    71 {
    72   NS_ASSERTION(NPVARIANT_IS_OBJECT(aVariant), "Wrong variant type!");
    73   return NPVARIANT_TO_OBJECT(aVariant);
    74 }
    76 inline const NPNetscapeFuncs*
    77 GetNetscapeFuncs(PluginInstanceParent* aInstance)
    78 {
    79   PluginModuleParent* module = aInstance->Module();
    80   if (!module) {
    81     NS_WARNING("Null module?!");
    82     return nullptr;
    83   }
    84   return module->GetNetscapeFuncs();
    85 }
    87 inline const NPNetscapeFuncs*
    88 GetNetscapeFuncs(NPObject* aObject)
    89 {
    90   NS_ASSERTION(aObject->_class == PluginScriptableObjectParent::GetClass(),
    91                "Bad class!");
    93   PluginInstanceParent* instance = GetInstance(aObject);
    94   if (!instance) {
    95     return nullptr;
    96   }
    98   return GetNetscapeFuncs(instance);
    99 }
   101 inline void
   102 ReleaseRemoteVariant(Variant& aVariant)
   103 {
   104   switch (aVariant.type()) {
   105     case Variant::TPPluginScriptableObjectParent: {
   106       PluginScriptableObjectParent* actor =
   107         const_cast<PluginScriptableObjectParent*>(
   108           reinterpret_cast<const PluginScriptableObjectParent*>(
   109             aVariant.get_PPluginScriptableObjectParent()));
   110       actor->Unprotect();
   111       break;
   112     }
   114     case Variant::TPPluginScriptableObjectChild: {
   115       NS_ASSERTION(PluginModuleChild::current(),
   116                    "Should only be running in the child!");
   117       PluginScriptableObjectChild* actor =
   118         const_cast<PluginScriptableObjectChild*>(
   119           reinterpret_cast<const PluginScriptableObjectChild*>(
   120             aVariant.get_PPluginScriptableObjectChild()));
   121       actor->Unprotect();
   122       break;
   123     }
   125   default:
   126     break; // Intentional fall-through for other variant types.
   127   }
   129   aVariant = mozilla::void_t();
   130 }
   132 bool
   133 ConvertToVariant(const Variant& aRemoteVariant,
   134                  NPVariant& aVariant,
   135                  PluginInstanceParent* aInstance = nullptr);
   137 template <class InstanceType>
   138 bool
   139 ConvertToRemoteVariant(const NPVariant& aVariant,
   140                        Variant& aRemoteVariant,
   141                        InstanceType* aInstance,
   142                        bool aProtectActors = false);
   144 class ProtectedVariant
   145 {
   146 public:
   147   ProtectedVariant(const NPVariant& aVariant,
   148                    PluginInstanceParent* aInstance)
   149   {
   150     mOk = ConvertToRemoteVariant(aVariant, mVariant, aInstance, true);
   151   }
   153   ProtectedVariant(const NPVariant& aVariant,
   154                    PluginInstanceChild* aInstance)
   155   {
   156     mOk = ConvertToRemoteVariant(aVariant, mVariant, aInstance, true);
   157   }
   159   ~ProtectedVariant() {
   160     ReleaseRemoteVariant(mVariant);
   161   }
   163   bool IsOk() {
   164     return mOk;
   165   }
   167   operator const Variant&() {
   168     return mVariant;
   169   }
   171 private:
   172   Variant mVariant;
   173   bool mOk;
   174 };
   176 class ProtectedVariantArray
   177 {
   178 public:
   179   ProtectedVariantArray(const NPVariant* aArgs,
   180                         uint32_t aCount,
   181                         PluginInstanceParent* aInstance)
   182     : mUsingShadowArray(false)
   183   {
   184     for (uint32_t index = 0; index < aCount; index++) {
   185       Variant* remoteVariant = mArray.AppendElement();
   186       if (!(remoteVariant && 
   187             ConvertToRemoteVariant(aArgs[index], *remoteVariant, aInstance,
   188                                    true))) {
   189         mOk = false;
   190         return;
   191       }
   192     }
   193     mOk = true;
   194   }
   196   ProtectedVariantArray(const NPVariant* aArgs,
   197                         uint32_t aCount,
   198                         PluginInstanceChild* aInstance)
   199     : mUsingShadowArray(false)
   200   {
   201     for (uint32_t index = 0; index < aCount; index++) {
   202       Variant* remoteVariant = mArray.AppendElement();
   203       if (!(remoteVariant && 
   204             ConvertToRemoteVariant(aArgs[index], *remoteVariant, aInstance,
   205                                    true))) {
   206         mOk = false;
   207         return;
   208       }
   209     }
   210     mOk = true;
   211   }
   213   ~ProtectedVariantArray()
   214   {
   215     InfallibleTArray<Variant>& vars = EnsureAndGetShadowArray();
   216     uint32_t count = vars.Length();
   217     for (uint32_t index = 0; index < count; index++) {
   218       ReleaseRemoteVariant(vars[index]);
   219     }
   220   }
   222   operator const InfallibleTArray<Variant>&()
   223   {
   224     return EnsureAndGetShadowArray();
   225   }
   227   bool IsOk()
   228   {
   229     return mOk;
   230   }
   232 private:
   233   InfallibleTArray<Variant>&
   234   EnsureAndGetShadowArray()
   235   {
   236     if (!mUsingShadowArray) {
   237       mShadowArray.SwapElements(mArray);
   238       mUsingShadowArray = true;
   239     }
   240     return mShadowArray;
   241   }
   243   // We convert the variants fallibly, but pass them to Call*()
   244   // methods as an infallible array
   245   nsTArray<Variant> mArray;
   246   InfallibleTArray<Variant> mShadowArray;
   247   bool mOk;
   248   bool mUsingShadowArray;
   249 };
   251 template<class ActorType>
   252 struct ProtectedActorTraits
   253 {
   254   static bool Nullable();
   255 };
   257 template<class ActorType, class Traits=ProtectedActorTraits<ActorType> >
   258 class ProtectedActor
   259 {
   260 public:
   261   ProtectedActor(ActorType* aActor) : mActor(aActor)
   262   {
   263     if (!Traits::Nullable()) {
   264       NS_ASSERTION(mActor, "This should never be null!");
   265     }
   266   }
   268   ~ProtectedActor()
   269   {
   270     if (Traits::Nullable() && !mActor)
   271       return;
   272     mActor->Unprotect();
   273   }
   275   ActorType* operator->()
   276   {
   277     return mActor;
   278   }
   280   operator bool()
   281   {
   282     return !!mActor;
   283   }
   285 private:
   286   ActorType* mActor;
   287 };
   289 template<>
   290 struct ProtectedActorTraits<PluginScriptableObjectParent>
   291 {
   292   static bool Nullable() { return true; }
   293 };
   295 template<>
   296 struct ProtectedActorTraits<PluginScriptableObjectChild>
   297 {
   298   static bool Nullable() { return false; }
   299 };
   301 } /* namespace plugins */
   302 } /* namespace mozilla */
   304 #include "PluginScriptableObjectUtils-inl.h"
   306 #endif /* dom_plugins_PluginScriptableObjectUtils_h */

mercurial