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

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

mercurial