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