dom/plugins/ipc/PluginScriptableObjectChild.cpp

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 #include "PluginScriptableObjectChild.h"
     8 #include "PluginScriptableObjectUtils.h"
     9 #include "PluginIdentifierChild.h"
    11 using namespace mozilla::plugins;
    13 // static
    14 NPObject*
    15 PluginScriptableObjectChild::ScriptableAllocate(NPP aInstance,
    16                                                 NPClass* aClass)
    17 {
    18   AssertPluginThread();
    20   if (aClass != GetClass()) {
    21     NS_RUNTIMEABORT("Huh?! Wrong class!");
    22   }
    24   return new ChildNPObject();
    25 }
    27 // static
    28 void
    29 PluginScriptableObjectChild::ScriptableInvalidate(NPObject* aObject)
    30 {
    31   AssertPluginThread();
    33   if (aObject->_class != GetClass()) {
    34     NS_RUNTIMEABORT("Don't know what kind of object this is!");
    35   }
    37   ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
    38   if (object->invalidated) {
    39     // This can happen more than once, and is just fine.
    40     return;
    41   }
    43   object->invalidated = true;
    44 }
    46 // static
    47 void
    48 PluginScriptableObjectChild::ScriptableDeallocate(NPObject* aObject)
    49 {
    50   AssertPluginThread();
    52   if (aObject->_class != GetClass()) {
    53     NS_RUNTIMEABORT("Don't know what kind of object this is!");
    54   }
    56   ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
    57   PluginScriptableObjectChild* actor = object->parent;
    58   if (actor) {
    59     NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
    60     actor->DropNPObject();
    61   }
    63   delete object;
    64 }
    66 // static
    67 bool
    68 PluginScriptableObjectChild::ScriptableHasMethod(NPObject* aObject,
    69                                                  NPIdentifier aName)
    70 {
    71   AssertPluginThread();
    73   if (aObject->_class != GetClass()) {
    74     NS_RUNTIMEABORT("Don't know what kind of object this is!");
    75   }
    77   ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
    78   if (object->invalidated) {
    79     NS_WARNING("Calling method on an invalidated object!");
    80     return false;
    81   }
    83   ProtectedActor<PluginScriptableObjectChild> actor(object->parent);
    84   NS_ASSERTION(actor, "This shouldn't ever be null!");
    85   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
    87   bool result;
    88   actor->CallHasMethod(static_cast<PPluginIdentifierChild*>(aName), &result);
    90   return result;
    91 }
    93 // static
    94 bool
    95 PluginScriptableObjectChild::ScriptableInvoke(NPObject* aObject,
    96                                               NPIdentifier aName,
    97                                               const NPVariant* aArgs,
    98                                               uint32_t aArgCount,
    99                                               NPVariant* aResult)
   100 {
   101   AssertPluginThread();
   103   if (aObject->_class != GetClass()) {
   104     NS_RUNTIMEABORT("Don't know what kind of object this is!");
   105   }
   107   ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
   108   if (object->invalidated) {
   109     NS_WARNING("Calling method on an invalidated object!");
   110     return false;
   111   }
   113   ProtectedActor<PluginScriptableObjectChild> actor(object->parent);
   114   NS_ASSERTION(actor, "This shouldn't ever be null!");
   115   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
   117   ProtectedVariantArray args(aArgs, aArgCount, actor->GetInstance());
   118   if (!args.IsOk()) {
   119     NS_ERROR("Failed to convert arguments!");
   120     return false;
   121   }
   123   Variant remoteResult;
   124   bool success;
   125   actor->CallInvoke(static_cast<PPluginIdentifierChild*>(aName), args,
   126                     &remoteResult, &success);
   128   if (!success) {
   129     return false;
   130   }
   132   ConvertToVariant(remoteResult, *aResult);
   133   return true;
   134 }
   136 // static
   137 bool
   138 PluginScriptableObjectChild::ScriptableInvokeDefault(NPObject* aObject,
   139                                                      const NPVariant* aArgs,
   140                                                      uint32_t aArgCount,
   141                                                      NPVariant* aResult)
   142 {
   143   AssertPluginThread();
   145   if (aObject->_class != GetClass()) {
   146     NS_RUNTIMEABORT("Don't know what kind of object this is!");
   147   }
   149   ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
   150   if (object->invalidated) {
   151     NS_WARNING("Calling method on an invalidated object!");
   152     return false;
   153   }
   155   ProtectedActor<PluginScriptableObjectChild> actor(object->parent);
   156   NS_ASSERTION(actor, "This shouldn't ever be null!");
   157   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
   159   ProtectedVariantArray args(aArgs, aArgCount, actor->GetInstance());
   160   if (!args.IsOk()) {
   161     NS_ERROR("Failed to convert arguments!");
   162     return false;
   163   }
   165   Variant remoteResult;
   166   bool success;
   167   actor->CallInvokeDefault(args, &remoteResult, &success);
   169   if (!success) {
   170     return false;
   171   }
   173   ConvertToVariant(remoteResult, *aResult);
   174   return true;
   175 }
   177 // static
   178 bool
   179 PluginScriptableObjectChild::ScriptableHasProperty(NPObject* aObject,
   180                                                    NPIdentifier aName)
   181 {
   182   AssertPluginThread();
   184   if (aObject->_class != GetClass()) {
   185     NS_RUNTIMEABORT("Don't know what kind of object this is!");
   186   }
   188   ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
   189   if (object->invalidated) {
   190     NS_WARNING("Calling method on an invalidated object!");
   191     return false;
   192   }
   194   ProtectedActor<PluginScriptableObjectChild> actor(object->parent);
   195   NS_ASSERTION(actor, "This shouldn't ever be null!");
   196   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
   198   bool result;
   199   actor->CallHasProperty(static_cast<PPluginIdentifierChild*>(aName), &result);
   201   return result;
   202 }
   204 // static
   205 bool
   206 PluginScriptableObjectChild::ScriptableGetProperty(NPObject* aObject,
   207                                                    NPIdentifier aName,
   208                                                    NPVariant* aResult)
   209 {
   210   AssertPluginThread();
   212   if (aObject->_class != GetClass()) {
   213     NS_RUNTIMEABORT("Don't know what kind of object this is!");
   214   }
   216   ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
   217   if (object->invalidated) {
   218     NS_WARNING("Calling method on an invalidated object!");
   219     return false;
   220   }
   222   ProtectedActor<PluginScriptableObjectChild> actor(object->parent);
   223   NS_ASSERTION(actor, "This shouldn't ever be null!");
   224   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
   226   Variant result;
   227   bool success;
   228   actor->CallGetParentProperty(static_cast<PPluginIdentifierChild*>(aName),
   229                                &result, &success);
   231   if (!success) {
   232     return false;
   233   }
   235   ConvertToVariant(result, *aResult);
   236   return true;
   237 }
   239 // static
   240 bool
   241 PluginScriptableObjectChild::ScriptableSetProperty(NPObject* aObject,
   242                                                    NPIdentifier aName,
   243                                                    const NPVariant* aValue)
   244 {
   245   AssertPluginThread();
   247   if (aObject->_class != GetClass()) {
   248     NS_RUNTIMEABORT("Don't know what kind of object this is!");
   249   }
   251   ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
   252   if (object->invalidated) {
   253     NS_WARNING("Calling method on an invalidated object!");
   254     return false;
   255   }
   257   ProtectedActor<PluginScriptableObjectChild> actor(object->parent);
   258   NS_ASSERTION(actor, "This shouldn't ever be null!");
   259   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
   261   ProtectedVariant value(*aValue, actor->GetInstance());
   262   if (!value.IsOk()) {
   263     NS_WARNING("Failed to convert variant!");
   264     return false;
   265   }
   267   bool success;
   268   actor->CallSetProperty(static_cast<PPluginIdentifierChild*>(aName), value,
   269                          &success);
   271   return success;
   272 }
   274 // static
   275 bool
   276 PluginScriptableObjectChild::ScriptableRemoveProperty(NPObject* aObject,
   277                                                       NPIdentifier aName)
   278 {
   279   AssertPluginThread();
   281   if (aObject->_class != GetClass()) {
   282     NS_RUNTIMEABORT("Don't know what kind of object this is!");
   283   }
   285   ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
   286   if (object->invalidated) {
   287     NS_WARNING("Calling method on an invalidated object!");
   288     return false;
   289   }
   291   ProtectedActor<PluginScriptableObjectChild> actor(object->parent);
   292   NS_ASSERTION(actor, "This shouldn't ever be null!");
   293   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
   295   bool success;
   296   actor->CallRemoveProperty(static_cast<PPluginIdentifierChild*>(aName),
   297                             &success);
   299   return success;
   300 }
   302 // static
   303 bool
   304 PluginScriptableObjectChild::ScriptableEnumerate(NPObject* aObject,
   305                                                  NPIdentifier** aIdentifiers,
   306                                                  uint32_t* aCount)
   307 {
   308   AssertPluginThread();
   310   if (aObject->_class != GetClass()) {
   311     NS_RUNTIMEABORT("Don't know what kind of object this is!");
   312   }
   314   ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
   315   if (object->invalidated) {
   316     NS_WARNING("Calling method on an invalidated object!");
   317     return false;
   318   }
   320   ProtectedActor<PluginScriptableObjectChild> actor(object->parent);
   321   NS_ASSERTION(actor, "This shouldn't ever be null!");
   322   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
   324   AutoInfallibleTArray<PPluginIdentifierChild*, 10> identifiers;
   325   bool success;
   326   actor->CallEnumerate(&identifiers, &success);
   328   if (!success) {
   329     return false;
   330   }
   332   *aCount = identifiers.Length();
   333   if (!*aCount) {
   334     *aIdentifiers = nullptr;
   335     return true;
   336   }
   338   *aIdentifiers = reinterpret_cast<NPIdentifier*>(
   339       PluginModuleChild::sBrowserFuncs.memalloc(*aCount * sizeof(NPIdentifier)));
   340   if (!*aIdentifiers) {
   341     NS_ERROR("Out of memory!");
   342     return false;
   343   }
   345   for (uint32_t index = 0; index < *aCount; index++) {
   346     (*aIdentifiers)[index] =
   347       static_cast<PPluginIdentifierChild*>(identifiers[index]);
   348   }
   349   return true;
   350 }
   352 // static
   353 bool
   354 PluginScriptableObjectChild::ScriptableConstruct(NPObject* aObject,
   355                                                  const NPVariant* aArgs,
   356                                                  uint32_t aArgCount,
   357                                                  NPVariant* aResult)
   358 {
   359   AssertPluginThread();
   361   if (aObject->_class != GetClass()) {
   362     NS_RUNTIMEABORT("Don't know what kind of object this is!");
   363   }
   365   ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
   366   if (object->invalidated) {
   367     NS_WARNING("Calling method on an invalidated object!");
   368     return false;
   369   }
   371   ProtectedActor<PluginScriptableObjectChild> actor(object->parent);
   372   NS_ASSERTION(actor, "This shouldn't ever be null!");
   373   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
   375   ProtectedVariantArray args(aArgs, aArgCount, actor->GetInstance());
   376   if (!args.IsOk()) {
   377     NS_ERROR("Failed to convert arguments!");
   378     return false;
   379   }
   381   Variant remoteResult;
   382   bool success;
   383   actor->CallConstruct(args, &remoteResult, &success);
   385   if (!success) {
   386     return false;
   387   }
   389   ConvertToVariant(remoteResult, *aResult);
   390   return true;
   391 }
   393 const NPClass PluginScriptableObjectChild::sNPClass = {
   394   NP_CLASS_STRUCT_VERSION,
   395   PluginScriptableObjectChild::ScriptableAllocate,
   396   PluginScriptableObjectChild::ScriptableDeallocate,
   397   PluginScriptableObjectChild::ScriptableInvalidate,
   398   PluginScriptableObjectChild::ScriptableHasMethod,
   399   PluginScriptableObjectChild::ScriptableInvoke,
   400   PluginScriptableObjectChild::ScriptableInvokeDefault,
   401   PluginScriptableObjectChild::ScriptableHasProperty,
   402   PluginScriptableObjectChild::ScriptableGetProperty,
   403   PluginScriptableObjectChild::ScriptableSetProperty,
   404   PluginScriptableObjectChild::ScriptableRemoveProperty,
   405   PluginScriptableObjectChild::ScriptableEnumerate,
   406   PluginScriptableObjectChild::ScriptableConstruct
   407 };
   409 PluginScriptableObjectChild::PluginScriptableObjectChild(
   410                                                      ScriptableObjectType aType)
   411 : mInstance(nullptr),
   412   mObject(nullptr),
   413   mInvalidated(false),
   414   mProtectCount(0),
   415   mType(aType)
   416 {
   417   AssertPluginThread();
   418 }
   420 PluginScriptableObjectChild::~PluginScriptableObjectChild()
   421 {
   422   AssertPluginThread();
   424   if (mObject) {
   425     PluginModuleChild::current()->UnregisterActorForNPObject(mObject);
   427     if (mObject->_class == GetClass()) {
   428       NS_ASSERTION(mType == Proxy, "Wrong type!");
   429       static_cast<ChildNPObject*>(mObject)->parent = nullptr;
   430     }
   431     else {
   432       NS_ASSERTION(mType == LocalObject, "Wrong type!");
   433       PluginModuleChild::sBrowserFuncs.releaseobject(mObject);
   434     }
   435   }
   436 }
   438 void
   439 PluginScriptableObjectChild::InitializeProxy()
   440 {
   441   AssertPluginThread();
   442   NS_ASSERTION(mType == Proxy, "Bad type!");
   443   NS_ASSERTION(!mObject, "Calling Initialize more than once!");
   444   NS_ASSERTION(!mInvalidated, "Already invalidated?!");
   446   mInstance = static_cast<PluginInstanceChild*>(Manager());
   447   NS_ASSERTION(mInstance, "Null manager?!");
   449   NPObject* object = CreateProxyObject();
   450   NS_ASSERTION(object, "Failed to create object!");
   452   if (!PluginModuleChild::current()->RegisterActorForNPObject(object, this)) {
   453     NS_ERROR("Out of memory?");
   454   }
   456   mObject = object;
   457 }
   459 void
   460 PluginScriptableObjectChild::InitializeLocal(NPObject* aObject)
   461 {
   462   AssertPluginThread();
   463   NS_ASSERTION(mType == LocalObject, "Bad type!");
   464   NS_ASSERTION(!mObject, "Calling Initialize more than once!");
   465   NS_ASSERTION(!mInvalidated, "Already invalidated?!");
   467   mInstance = static_cast<PluginInstanceChild*>(Manager());
   468   NS_ASSERTION(mInstance, "Null manager?!");
   470   PluginModuleChild::sBrowserFuncs.retainobject(aObject);
   472   NS_ASSERTION(!mProtectCount, "Should be zero!");
   473   mProtectCount++;
   475   if (!PluginModuleChild::current()->RegisterActorForNPObject(aObject, this)) {
   476       NS_ERROR("Out of memory?");
   477   }
   479   mObject = aObject;
   480 }
   482 NPObject*
   483 PluginScriptableObjectChild::CreateProxyObject()
   484 {
   485   NS_ASSERTION(mInstance, "Must have an instance!");
   486   NS_ASSERTION(mType == Proxy, "Shouldn't call this for non-proxy object!");
   488   NPClass* proxyClass = const_cast<NPClass*>(GetClass());
   489   NPObject* npobject =
   490     PluginModuleChild::sBrowserFuncs.createobject(mInstance->GetNPP(),
   491                                                   proxyClass);
   492   NS_ASSERTION(npobject, "Failed to create object?!");
   493   NS_ASSERTION(npobject->_class == GetClass(), "Wrong kind of object!");
   494   NS_ASSERTION(npobject->referenceCount == 1, "Some kind of live object!");
   496   ChildNPObject* object = static_cast<ChildNPObject*>(npobject);
   497   NS_ASSERTION(!object->invalidated, "Bad object!");
   498   NS_ASSERTION(!object->parent, "Bad object!");
   500   // We don't want to have the actor own this object but rather let the object
   501   // own this actor. Set the reference count to 0 here so that when the object
   502   // dies we will send the destructor message to the child.
   503   object->referenceCount = 0;
   504   NS_LOG_RELEASE(object, 0, "NPObject");
   506   object->parent = const_cast<PluginScriptableObjectChild*>(this);
   507   return object;
   508 }
   510 bool
   511 PluginScriptableObjectChild::ResurrectProxyObject()
   512 {
   513   NS_ASSERTION(mInstance, "Must have an instance already!");
   514   NS_ASSERTION(!mObject, "Should not have an object already!");
   515   NS_ASSERTION(mType == Proxy, "Shouldn't call this for non-proxy object!");
   517   NPObject* object = CreateProxyObject();
   518   if (!object) {
   519     NS_WARNING("Failed to create object!");
   520     return false;
   521   }
   523   InitializeProxy();
   524   NS_ASSERTION(mObject, "Initialize failed!");
   526   SendProtect();
   527   return true;
   528 }
   530 NPObject*
   531 PluginScriptableObjectChild::GetObject(bool aCanResurrect)
   532 {
   533   if (!mObject && aCanResurrect && !ResurrectProxyObject()) {
   534     NS_ERROR("Null object!");
   535     return nullptr;
   536   }
   537   return mObject;
   538 }
   540 void
   541 PluginScriptableObjectChild::Protect()
   542 {
   543   NS_ASSERTION(mObject, "No object!");
   544   NS_ASSERTION(mProtectCount >= 0, "Negative retain count?!");
   546   if (mType == LocalObject) {
   547     ++mProtectCount;
   548   }
   549 }
   551 void
   552 PluginScriptableObjectChild::Unprotect()
   553 {
   554   NS_ASSERTION(mObject, "Bad state!");
   555   NS_ASSERTION(mProtectCount >= 0, "Negative retain count?!");
   557   if (mType == LocalObject) {
   558     if (--mProtectCount == 0) {
   559       PluginScriptableObjectChild::Send__delete__(this);
   560     }
   561   }
   562 }
   564 void
   565 PluginScriptableObjectChild::DropNPObject()
   566 {
   567   NS_ASSERTION(mObject, "Invalidated object!");
   568   NS_ASSERTION(mObject->_class == GetClass(), "Wrong type of object!");
   569   NS_ASSERTION(mType == Proxy, "Shouldn't call this for non-proxy object!");
   571   // We think we're about to be deleted, but we could be racing with the other
   572   // process.
   573   PluginModuleChild::current()->UnregisterActorForNPObject(mObject);
   574   mObject = nullptr;
   576   SendUnprotect();
   577 }
   579 void
   580 PluginScriptableObjectChild::NPObjectDestroyed()
   581 {
   582   NS_ASSERTION(LocalObject == mType,
   583                "ScriptableDeallocate should have handled this for proxies");
   584   mInvalidated = true;
   585   mObject = nullptr;
   586 }
   588 bool
   589 PluginScriptableObjectChild::AnswerInvalidate()
   590 {
   591   AssertPluginThread();
   593   if (mInvalidated) {
   594     return true;
   595   }
   597   mInvalidated = true;
   599   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
   600   NS_ASSERTION(mType == LocalObject, "Bad type!");
   602   if (mObject->_class && mObject->_class->invalidate) {
   603     mObject->_class->invalidate(mObject);
   604   }
   606   Unprotect();
   608   return true;
   609 }
   611 bool
   612 PluginScriptableObjectChild::AnswerHasMethod(PPluginIdentifierChild* aId,
   613                                              bool* aHasMethod)
   614 {
   615   AssertPluginThread();
   617   if (mInvalidated) {
   618     NS_WARNING("Calling AnswerHasMethod with an invalidated object!");
   619     *aHasMethod = false;
   620     return true;
   621   }
   623   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
   624   NS_ASSERTION(mType == LocalObject, "Bad type!");
   626   if (!(mObject->_class && mObject->_class->hasMethod)) {
   627     *aHasMethod = false;
   628     return true;
   629   }
   631   PluginIdentifierChild::StackIdentifier id(aId);
   632   *aHasMethod = mObject->_class->hasMethod(mObject, id->ToNPIdentifier());
   633   return true;
   634 }
   636 bool
   637 PluginScriptableObjectChild::AnswerInvoke(PPluginIdentifierChild* aId,
   638                                           const InfallibleTArray<Variant>& aArgs,
   639                                           Variant* aResult,
   640                                           bool* aSuccess)
   641 {
   642   AssertPluginThread();
   644   if (mInvalidated) {
   645     NS_WARNING("Calling AnswerInvoke with an invalidated object!");
   646     *aResult = void_t();
   647     *aSuccess = false;
   648     return true;
   649   }
   651   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
   652   NS_ASSERTION(mType == LocalObject, "Bad type!");
   654   if (!(mObject->_class && mObject->_class->invoke)) {
   655     *aResult = void_t();
   656     *aSuccess = false;
   657     return true;
   658   }
   660   AutoFallibleTArray<NPVariant, 10> convertedArgs;
   661   uint32_t argCount = aArgs.Length();
   663   if (!convertedArgs.SetLength(argCount)) {
   664     *aResult = void_t();
   665     *aSuccess = false;
   666     return true;
   667   }
   669   for (uint32_t index = 0; index < argCount; index++) {
   670     ConvertToVariant(aArgs[index], convertedArgs[index]);
   671   }
   673   NPVariant result;
   674   VOID_TO_NPVARIANT(result);
   675   PluginIdentifierChild::StackIdentifier id(aId);
   676   bool success = mObject->_class->invoke(mObject, id->ToNPIdentifier(),
   677                                          convertedArgs.Elements(), argCount,
   678                                          &result);
   680   for (uint32_t index = 0; index < argCount; index++) {
   681     PluginModuleChild::sBrowserFuncs.releasevariantvalue(&convertedArgs[index]);
   682   }
   684   if (!success) {
   685     *aResult = void_t();
   686     *aSuccess = false;
   687     return true;
   688   }
   690   Variant convertedResult;
   691   success = ConvertToRemoteVariant(result, convertedResult, GetInstance(),
   692                                    false);
   694   DeferNPVariantLastRelease(&PluginModuleChild::sBrowserFuncs, &result);
   696   if (!success) {
   697     *aResult = void_t();
   698     *aSuccess = false;
   699     return true;
   700   }
   702   *aSuccess = true;
   703   *aResult = convertedResult;
   704   return true;
   705 }
   707 bool
   708 PluginScriptableObjectChild::AnswerInvokeDefault(const InfallibleTArray<Variant>& aArgs,
   709                                                  Variant* aResult,
   710                                                  bool* aSuccess)
   711 {
   712   AssertPluginThread();
   714   if (mInvalidated) {
   715     NS_WARNING("Calling AnswerInvokeDefault with an invalidated object!");
   716     *aResult = void_t();
   717     *aSuccess = false;
   718     return true;
   719   }
   721   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
   722   NS_ASSERTION(mType == LocalObject, "Bad type!");
   724   if (!(mObject->_class && mObject->_class->invokeDefault)) {
   725     *aResult = void_t();
   726     *aSuccess = false;
   727     return true;
   728   }
   730   AutoFallibleTArray<NPVariant, 10> convertedArgs;
   731   uint32_t argCount = aArgs.Length();
   733   if (!convertedArgs.SetLength(argCount)) {
   734     *aResult = void_t();
   735     *aSuccess = false;
   736     return true;
   737   }
   739   for (uint32_t index = 0; index < argCount; index++) {
   740     ConvertToVariant(aArgs[index], convertedArgs[index]);
   741   }
   743   NPVariant result;
   744   VOID_TO_NPVARIANT(result);
   745   bool success = mObject->_class->invokeDefault(mObject,
   746                                                 convertedArgs.Elements(),
   747                                                 argCount, &result);
   749   for (uint32_t index = 0; index < argCount; index++) {
   750     PluginModuleChild::sBrowserFuncs.releasevariantvalue(&convertedArgs[index]);
   751   }
   753   if (!success) {
   754     *aResult = void_t();
   755     *aSuccess = false;
   756     return true;
   757   }
   759   Variant convertedResult;
   760   success = ConvertToRemoteVariant(result, convertedResult, GetInstance(),
   761                                    false);
   763   DeferNPVariantLastRelease(&PluginModuleChild::sBrowserFuncs, &result);
   765   if (!success) {
   766     *aResult = void_t();
   767     *aSuccess = false;
   768     return true;
   769   }
   771   *aResult = convertedResult;
   772   *aSuccess = true;
   773   return true;
   774 }
   776 bool
   777 PluginScriptableObjectChild::AnswerHasProperty(PPluginIdentifierChild* aId,
   778                                                bool* aHasProperty)
   779 {
   780   AssertPluginThread();
   782   if (mInvalidated) {
   783     NS_WARNING("Calling AnswerHasProperty with an invalidated object!");
   784     *aHasProperty = false;
   785     return true;
   786   }
   788   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
   789   NS_ASSERTION(mType == LocalObject, "Bad type!");
   791   if (!(mObject->_class && mObject->_class->hasProperty)) {
   792     *aHasProperty = false;
   793     return true;
   794   }
   796   PluginIdentifierChild::StackIdentifier id(aId);
   797   *aHasProperty = mObject->_class->hasProperty(mObject, id->ToNPIdentifier());
   798   return true;
   799 }
   801 bool
   802 PluginScriptableObjectChild::AnswerGetChildProperty(PPluginIdentifierChild* aId,
   803                                                     bool* aHasProperty,
   804                                                     bool* aHasMethod,
   805                                                     Variant* aResult,
   806                                                     bool* aSuccess)
   807 {
   808   AssertPluginThread();
   810   *aHasProperty = *aHasMethod = *aSuccess = false;
   811   *aResult = void_t();
   813   if (mInvalidated) {
   814     NS_WARNING("Calling AnswerGetProperty with an invalidated object!");
   815     return true;
   816   }
   818   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
   819   NS_ASSERTION(mType == LocalObject, "Bad type!");
   821   if (!(mObject->_class && mObject->_class->hasProperty &&
   822         mObject->_class->hasMethod && mObject->_class->getProperty)) {
   823     return true;
   824   }
   826   PluginIdentifierChild::StackIdentifier stackID(aId);
   827   NPIdentifier id = stackID->ToNPIdentifier();
   829   *aHasProperty = mObject->_class->hasProperty(mObject, id);
   830   *aHasMethod = mObject->_class->hasMethod(mObject, id);
   832   if (*aHasProperty) {
   833     NPVariant result;
   834     VOID_TO_NPVARIANT(result);
   836     if (!mObject->_class->getProperty(mObject, id, &result)) {
   837       return true;
   838     }
   840     Variant converted;
   841     if ((*aSuccess = ConvertToRemoteVariant(result, converted, GetInstance(),
   842                                             false))) {
   843       DeferNPVariantLastRelease(&PluginModuleChild::sBrowserFuncs, &result);
   844       *aResult = converted;
   845     }
   846   }
   848   return true;
   849 }
   851 bool
   852 PluginScriptableObjectChild::AnswerSetProperty(PPluginIdentifierChild* aId,
   853                                                const Variant& aValue,
   854                                                bool* aSuccess)
   855 {
   856   AssertPluginThread();
   858   if (mInvalidated) {
   859     NS_WARNING("Calling AnswerSetProperty with an invalidated object!");
   860     *aSuccess = false;
   861     return true;
   862   }
   864   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
   865   NS_ASSERTION(mType == LocalObject, "Bad type!");
   867   if (!(mObject->_class && mObject->_class->hasProperty &&
   868         mObject->_class->setProperty)) {
   869     *aSuccess = false;
   870     return true;
   871   }
   873   PluginIdentifierChild::StackIdentifier stackID(aId);
   874   NPIdentifier id = stackID->ToNPIdentifier();
   876   if (!mObject->_class->hasProperty(mObject, id)) {
   877     *aSuccess = false;
   878     return true;
   879   }
   881   NPVariant converted;
   882   ConvertToVariant(aValue, converted);
   884   if ((*aSuccess = mObject->_class->setProperty(mObject, id, &converted))) {
   885     PluginModuleChild::sBrowserFuncs.releasevariantvalue(&converted);
   886   }
   887   return true;
   888 }
   890 bool
   891 PluginScriptableObjectChild::AnswerRemoveProperty(PPluginIdentifierChild* aId,
   892                                                   bool* aSuccess)
   893 {
   894   AssertPluginThread();
   896   if (mInvalidated) {
   897     NS_WARNING("Calling AnswerRemoveProperty with an invalidated object!");
   898     *aSuccess = false;
   899     return true;
   900   }
   902   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
   903   NS_ASSERTION(mType == LocalObject, "Bad type!");
   905   if (!(mObject->_class && mObject->_class->hasProperty &&
   906         mObject->_class->removeProperty)) {
   907     *aSuccess = false;
   908     return true;
   909   }
   911   PluginIdentifierChild::StackIdentifier stackID(aId);
   912   NPIdentifier id = stackID->ToNPIdentifier();
   913   *aSuccess = mObject->_class->hasProperty(mObject, id) ?
   914               mObject->_class->removeProperty(mObject, id) :
   915               true;
   917   return true;
   918 }
   920 bool
   921 PluginScriptableObjectChild::AnswerEnumerate(InfallibleTArray<PPluginIdentifierChild*>* aProperties,
   922                                              bool* aSuccess)
   923 {
   924   AssertPluginThread();
   926   if (mInvalidated) {
   927     NS_WARNING("Calling AnswerEnumerate with an invalidated object!");
   928     *aSuccess = false;
   929     return true;
   930   }
   932   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
   933   NS_ASSERTION(mType == LocalObject, "Bad type!");
   935   if (!(mObject->_class && mObject->_class->enumerate)) {
   936     *aSuccess = false;
   937     return true;
   938   }
   940   NPIdentifier* ids;
   941   uint32_t idCount;
   942   if (!mObject->_class->enumerate(mObject, &ids, &idCount)) {
   943     *aSuccess = false;
   944     return true;
   945   }
   947   aProperties->SetCapacity(idCount);
   949   for (uint32_t index = 0; index < idCount; index++) {
   950     PluginIdentifierChild* id = static_cast<PluginIdentifierChild*>(ids[index]);
   951     aProperties->AppendElement(id);
   952   }
   954   PluginModuleChild::sBrowserFuncs.memfree(ids);
   955   *aSuccess = true;
   956   return true;
   957 }
   959 bool
   960 PluginScriptableObjectChild::AnswerConstruct(const InfallibleTArray<Variant>& aArgs,
   961                                              Variant* aResult,
   962                                              bool* aSuccess)
   963 {
   964   AssertPluginThread();
   966   if (mInvalidated) {
   967     NS_WARNING("Calling AnswerConstruct with an invalidated object!");
   968     *aResult = void_t();
   969     *aSuccess = false;
   970     return true;
   971   }
   973   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
   974   NS_ASSERTION(mType == LocalObject, "Bad type!");
   976   if (!(mObject->_class && mObject->_class->construct)) {
   977     *aResult = void_t();
   978     *aSuccess = false;
   979     return true;
   980   }
   982   AutoFallibleTArray<NPVariant, 10> convertedArgs;
   983   uint32_t argCount = aArgs.Length();
   985   if (!convertedArgs.SetLength(argCount)) {
   986     *aResult = void_t();
   987     *aSuccess = false;
   988     return true;
   989   }
   991   for (uint32_t index = 0; index < argCount; index++) {
   992     ConvertToVariant(aArgs[index], convertedArgs[index]);
   993   }
   995   NPVariant result;
   996   VOID_TO_NPVARIANT(result);
   997   bool success = mObject->_class->construct(mObject, convertedArgs.Elements(),
   998                                             argCount, &result);
  1000   for (uint32_t index = 0; index < argCount; index++) {
  1001     PluginModuleChild::sBrowserFuncs.releasevariantvalue(&convertedArgs[index]);
  1004   if (!success) {
  1005     *aResult = void_t();
  1006     *aSuccess = false;
  1007     return true;
  1010   Variant convertedResult;
  1011   success = ConvertToRemoteVariant(result, convertedResult, GetInstance(),
  1012                                    false);
  1014   DeferNPVariantLastRelease(&PluginModuleChild::sBrowserFuncs, &result);
  1016   if (!success) {
  1017     *aResult = void_t();
  1018     *aSuccess = false;
  1019     return true;
  1022   *aResult = convertedResult;
  1023   *aSuccess = true;
  1024   return true;
  1027 bool
  1028 PluginScriptableObjectChild::RecvProtect()
  1030   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
  1031   NS_ASSERTION(mType == LocalObject, "Bad type!");
  1033   Protect();
  1034   return true;
  1037 bool
  1038 PluginScriptableObjectChild::RecvUnprotect()
  1040   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
  1041   NS_ASSERTION(mType == LocalObject, "Bad type!");
  1043   Unprotect();
  1044   return true;
  1047 bool
  1048 PluginScriptableObjectChild::Evaluate(NPString* aScript,
  1049                                       NPVariant* aResult)
  1051   nsDependentCString script("");
  1052   if (aScript->UTF8Characters && aScript->UTF8Length) {
  1053     script.Rebind(aScript->UTF8Characters, aScript->UTF8Length);
  1056   bool success;
  1057   Variant result;
  1058   CallNPN_Evaluate(script, &result, &success);
  1060   if (!success) {
  1061     return false;
  1064   ConvertToVariant(result, *aResult);
  1065   return true;

mercurial