Bug 558503 - [OOPP] Watching netflix video: Silverlight crashes the plugin helper...
[mozilla-central.git] / dom / plugins / PluginMessageUtils.h
blobdcb188f021a2fc365d1d303449be698f64ad240c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: sw=4 ts=4 et :
3 * ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
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/
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.
16 * The Original Code is Mozilla Plugin App.
18 * The Initial Developer of the Original Code is
19 * Chris Jones <jones.chris.g@gmail.com>
20 * Portions created by the Initial Developer are Copyright (C) 2009
21 * the Initial Developer. All Rights Reserved.
23 * Contributor(s):
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.
37 * ***** END LICENSE BLOCK ***** */
39 #ifndef DOM_PLUGINS_PLUGINMESSAGEUTILS_H
40 #define DOM_PLUGINS_PLUGINMESSAGEUTILS_H
42 #include "IPC/IPCMessageUtils.h"
43 #include "base/message_loop.h"
45 #include "mozilla/ipc/RPCChannel.h"
47 #include "npapi.h"
48 #include "npruntime.h"
49 #include "npfunctions.h"
50 #include "nsAutoPtr.h"
51 #include "nsStringGlue.h"
52 #include "nsTArray.h"
53 #include "nsThreadUtils.h"
54 #include "prlog.h"
55 #include "nsHashKeys.h"
56 #ifdef MOZ_CRASHREPORTER
57 # include "nsExceptionHandler.h"
58 #endif
60 namespace mozilla {
62 // XXX might want to move these to nscore.h or something, they can be
63 // generally useful
64 struct void_t { };
65 struct null_t { };
67 namespace plugins {
69 enum ScriptableObjectType
71 LocalObject,
72 Proxy
75 mozilla::ipc::RPCChannel::RacyRPCPolicy
76 MediateRace(const mozilla::ipc::RPCChannel::Message& parent,
77 const mozilla::ipc::RPCChannel::Message& child);
79 extern PRLogModuleInfo* gPluginLog;
81 #if defined(_MSC_VER)
82 #define FULLFUNCTION __FUNCSIG__
83 #elif (__GNUC__ >= 4)
84 #define FULLFUNCTION __PRETTY_FUNCTION__
85 #else
86 #define FULLFUNCTION __FUNCTION__
87 #endif
89 #define PLUGIN_LOG_DEBUG(args) PR_LOG(gPluginLog, PR_LOG_DEBUG, args)
90 #define PLUGIN_LOG_DEBUG_FUNCTION PR_LOG(gPluginLog, PR_LOG_DEBUG, ("%s", FULLFUNCTION))
91 #define PLUGIN_LOG_DEBUG_METHOD PR_LOG(gPluginLog, PR_LOG_DEBUG, ("%s [%p]", FULLFUNCTION, (void*) this))
93 /**
94 * This is NPByteRange without the linked list.
96 struct IPCByteRange
98 int32_t offset;
99 uint32_t length;
102 typedef std::vector<IPCByteRange> IPCByteRanges;
104 typedef nsCString Buffer;
106 struct NPRemoteWindow
108 unsigned long window;
109 int32_t x;
110 int32_t y;
111 uint32_t width;
112 uint32_t height;
113 NPRect clipRect;
114 NPWindowType type;
115 #if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
116 VisualID visualID;
117 Colormap colormap;
118 #endif /* XP_UNIX */
119 #if defined(XP_WIN)
120 base::SharedMemoryHandle surfaceHandle;
121 #endif
124 #ifdef XP_WIN
125 typedef HWND NativeWindowHandle;
126 #elif defined(MOZ_X11)
127 typedef XID NativeWindowHandle;
128 #elif defined(XP_MACOSX)
129 typedef intptr_t NativeWindowHandle; // never actually used, will always be 0
130 #else
131 #error Need NativeWindowHandle for this platform
132 #endif
134 #ifdef MOZ_CRASHREPORTER
135 typedef CrashReporter::ThreadId NativeThreadId;
136 #else
137 // unused in this case
138 typedef int32 NativeThreadId;
139 #endif
141 // XXX maybe not the best place for these. better one?
143 #define VARSTR(v_) case v_: return #v_
144 inline const char* const
145 NPPVariableToString(NPPVariable aVar)
147 switch (aVar) {
148 VARSTR(NPPVpluginNameString);
149 VARSTR(NPPVpluginDescriptionString);
150 VARSTR(NPPVpluginWindowBool);
151 VARSTR(NPPVpluginTransparentBool);
152 VARSTR(NPPVjavaClass);
153 VARSTR(NPPVpluginWindowSize);
154 VARSTR(NPPVpluginTimerInterval);
156 VARSTR(NPPVpluginScriptableInstance);
157 VARSTR(NPPVpluginScriptableIID);
159 VARSTR(NPPVjavascriptPushCallerBool);
161 VARSTR(NPPVpluginKeepLibraryInMemory);
162 VARSTR(NPPVpluginNeedsXEmbed);
164 VARSTR(NPPVpluginScriptableNPObject);
166 VARSTR(NPPVformValue);
168 VARSTR(NPPVpluginUrlRequestsDisplayedBool);
170 VARSTR(NPPVpluginWantsAllNetworkStreams);
172 #ifdef XP_MACOSX
173 VARSTR(NPPVpluginDrawingModel);
174 VARSTR(NPPVpluginEventModel);
175 #endif
177 default: return "???";
181 inline const char*
182 NPNVariableToString(NPNVariable aVar)
184 switch(aVar) {
185 VARSTR(NPNVxDisplay);
186 VARSTR(NPNVxtAppContext);
187 VARSTR(NPNVnetscapeWindow);
188 VARSTR(NPNVjavascriptEnabledBool);
189 VARSTR(NPNVasdEnabledBool);
190 VARSTR(NPNVisOfflineBool);
192 VARSTR(NPNVserviceManager);
193 VARSTR(NPNVDOMElement);
194 VARSTR(NPNVDOMWindow);
195 VARSTR(NPNVToolkit);
196 VARSTR(NPNVSupportsXEmbedBool);
198 VARSTR(NPNVWindowNPObject);
200 VARSTR(NPNVPluginElementNPObject);
202 VARSTR(NPNVSupportsWindowless);
204 VARSTR(NPNVprivateModeBool);
206 default: return "???";
209 #undef VARSTR
211 inline bool IsPluginThread()
213 MessageLoop* loop = MessageLoop::current();
214 if (!loop)
215 return false;
216 return (loop->type() == MessageLoop::TYPE_UI);
219 inline void AssertPluginThread()
221 NS_ASSERTION(IsPluginThread(), "Should be on the plugin's main thread!");
224 #define ENSURE_PLUGIN_THREAD(retval) \
225 PR_BEGIN_MACRO \
226 if (!IsPluginThread()) { \
227 NS_WARNING("Not running on the plugin's main thread!"); \
228 return (retval); \
230 PR_END_MACRO
232 #define ENSURE_PLUGIN_THREAD_VOID() \
233 PR_BEGIN_MACRO \
234 if (!IsPluginThread()) { \
235 NS_WARNING("Not running on the plugin's main thread!"); \
236 return; \
238 PR_END_MACRO
240 void DeferNPObjectLastRelease(const NPNetscapeFuncs* f, NPObject* o);
241 void DeferNPVariantLastRelease(const NPNetscapeFuncs* f, NPVariant* v);
243 // in NPAPI, char* == NULL is sometimes meaningful. the following is
244 // helper code for dealing with nullable nsCString's
245 inline nsCString
246 NullableString(const char* aString)
248 if (!aString) {
249 nsCString str;
250 str.SetIsVoid(PR_TRUE);
251 return str;
253 return nsCString(aString);
256 inline const char*
257 NullableStringGet(const nsCString& str)
259 if (str.IsVoid())
260 return NULL;
262 return str.get();
265 struct DeletingObjectEntry : public nsPtrHashKey<NPObject>
267 DeletingObjectEntry(const NPObject* key)
268 : nsPtrHashKey<NPObject>(key)
269 , mDeleted(false)
272 bool mDeleted;
275 } /* namespace plugins */
277 } /* namespace mozilla */
279 namespace IPC {
281 template <>
282 struct ParamTraits<NPRect>
284 typedef NPRect paramType;
286 static void Write(Message* aMsg, const paramType& aParam)
288 WriteParam(aMsg, aParam.top);
289 WriteParam(aMsg, aParam.left);
290 WriteParam(aMsg, aParam.bottom);
291 WriteParam(aMsg, aParam.right);
294 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
296 uint16_t top, left, bottom, right;
297 if (ReadParam(aMsg, aIter, &top) &&
298 ReadParam(aMsg, aIter, &left) &&
299 ReadParam(aMsg, aIter, &bottom) &&
300 ReadParam(aMsg, aIter, &right)) {
301 aResult->top = top;
302 aResult->left = left;
303 aResult->bottom = bottom;
304 aResult->right = right;
305 return true;
307 return false;
310 static void Log(const paramType& aParam, std::wstring* aLog)
312 aLog->append(StringPrintf(L"[%u, %u, %u, %u]", aParam.top, aParam.left,
313 aParam.bottom, aParam.right));
317 template <>
318 struct ParamTraits<NPWindowType>
320 typedef NPWindowType paramType;
322 static void Write(Message* aMsg, const paramType& aParam)
324 aMsg->WriteInt16(int16(aParam));
327 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
329 int16 result;
330 if (aMsg->ReadInt16(aIter, &result)) {
331 *aResult = paramType(result);
332 return true;
334 return false;
337 static void Log(const paramType& aParam, std::wstring* aLog)
339 aLog->append(StringPrintf(L"%d", int16(aParam)));
343 template <>
344 struct ParamTraits<mozilla::plugins::NPRemoteWindow>
346 typedef mozilla::plugins::NPRemoteWindow paramType;
348 static void Write(Message* aMsg, const paramType& aParam)
350 aMsg->WriteULong(aParam.window);
351 WriteParam(aMsg, aParam.x);
352 WriteParam(aMsg, aParam.y);
353 WriteParam(aMsg, aParam.width);
354 WriteParam(aMsg, aParam.height);
355 WriteParam(aMsg, aParam.clipRect);
356 WriteParam(aMsg, aParam.type);
357 #if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
358 aMsg->WriteULong(aParam.visualID);
359 aMsg->WriteULong(aParam.colormap);
360 #endif
361 #if defined(XP_WIN)
362 WriteParam(aMsg, aParam.surfaceHandle);
363 #endif
366 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
368 unsigned long window;
369 int32_t x, y;
370 uint32_t width, height;
371 NPRect clipRect;
372 NPWindowType type;
373 if (!(aMsg->ReadULong(aIter, &window) &&
374 ReadParam(aMsg, aIter, &x) &&
375 ReadParam(aMsg, aIter, &y) &&
376 ReadParam(aMsg, aIter, &width) &&
377 ReadParam(aMsg, aIter, &height) &&
378 ReadParam(aMsg, aIter, &clipRect) &&
379 ReadParam(aMsg, aIter, &type)))
380 return false;
382 #if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
383 unsigned long visualID;
384 unsigned long colormap;
385 if (!(aMsg->ReadULong(aIter, &visualID) &&
386 aMsg->ReadULong(aIter, &colormap)))
387 return false;
388 #endif
390 #if defined(XP_WIN)
391 base::SharedMemoryHandle surfaceHandle;
392 if (!ReadParam(aMsg, aIter, &surfaceHandle))
393 return false;
394 #endif
396 aResult->window = window;
397 aResult->x = x;
398 aResult->y = y;
399 aResult->width = width;
400 aResult->height = height;
401 aResult->clipRect = clipRect;
402 aResult->type = type;
403 #if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
404 aResult->visualID = visualID;
405 aResult->colormap = colormap;
406 #endif
407 #if defined(XP_WIN)
408 aResult->surfaceHandle = surfaceHandle;
409 #endif
410 return true;
413 static void Log(const paramType& aParam, std::wstring* aLog)
415 aLog->append(StringPrintf(L"[%u, %d, %d, %u, %u, %d",
416 (unsigned long)aParam.window,
417 aParam.x, aParam.y, aParam.width,
418 aParam.height, (long)aParam.type));
422 template <>
423 struct ParamTraits<NPString>
425 typedef NPString paramType;
427 static void Write(Message* aMsg, const paramType& aParam)
429 WriteParam(aMsg, aParam.UTF8Length);
430 aMsg->WriteBytes(aParam.UTF8Characters,
431 aParam.UTF8Length * sizeof(NPUTF8));
434 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
436 if (ReadParam(aMsg, aIter, &aResult->UTF8Length)) {
437 int byteCount = aResult->UTF8Length * sizeof(NPUTF8);
438 if (!byteCount) {
439 aResult->UTF8Characters = "\0";
440 return true;
443 const char* messageBuffer = nsnull;
444 nsAutoArrayPtr<char> newBuffer(new char[byteCount]);
445 if (newBuffer && aMsg->ReadBytes(aIter, &messageBuffer, byteCount )) {
446 memcpy((void*)messageBuffer, newBuffer.get(), byteCount);
447 aResult->UTF8Characters = newBuffer.forget();
448 return true;
451 return false;
454 static void Log(const paramType& aParam, std::wstring* aLog)
456 aLog->append(StringPrintf(L"%s", aParam.UTF8Characters));
460 #ifdef XP_MACOSX
461 template <>
462 struct ParamTraits<NPNSString*>
464 typedef NPNSString* paramType;
466 // Empty string writes a length of 0 and no buffer.
467 // We don't write a NULL terminating character in buffers.
468 static void Write(Message* aMsg, const paramType& aParam)
470 CFStringRef cfString = (CFStringRef)aParam;
471 long length = ::CFStringGetLength(cfString);
472 WriteParam(aMsg, length);
473 if (length == 0) {
474 return;
477 // Attempt to get characters without any allocation/conversion.
478 if (::CFStringGetCharactersPtr(cfString)) {
479 aMsg->WriteBytes(::CFStringGetCharactersPtr(cfString), length * sizeof(UniChar));
480 } else {
481 UniChar *buffer = (UniChar*)moz_xmalloc(length * sizeof(UniChar));
482 ::CFStringGetCharacters(cfString, ::CFRangeMake(0, length), buffer);
483 aMsg->WriteBytes(buffer, length * sizeof(UniChar));
484 free(buffer);
488 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
490 long length;
491 if (!ReadParam(aMsg, aIter, &length)) {
492 return false;
495 UniChar* buffer = nsnull;
496 if (length != 0) {
497 if (!aMsg->ReadBytes(aIter, (const char**)&buffer, length * sizeof(UniChar)) ||
498 !buffer) {
499 return false;
503 *aResult = (NPNSString*)::CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8*)buffer,
504 length * sizeof(UniChar),
505 kCFStringEncodingUTF16, false);
506 if (!*aResult) {
507 return false;
510 return true;
513 #endif
515 template <>
516 struct ParamTraits<NPVariant>
518 typedef NPVariant paramType;
520 static void Write(Message* aMsg, const paramType& aParam)
522 if (NPVARIANT_IS_VOID(aParam)) {
523 aMsg->WriteInt(0);
524 return;
527 if (NPVARIANT_IS_NULL(aParam)) {
528 aMsg->WriteInt(1);
529 return;
532 if (NPVARIANT_IS_BOOLEAN(aParam)) {
533 aMsg->WriteInt(2);
534 WriteParam(aMsg, NPVARIANT_TO_BOOLEAN(aParam));
535 return;
538 if (NPVARIANT_IS_INT32(aParam)) {
539 aMsg->WriteInt(3);
540 WriteParam(aMsg, NPVARIANT_TO_INT32(aParam));
541 return;
544 if (NPVARIANT_IS_DOUBLE(aParam)) {
545 aMsg->WriteInt(4);
546 WriteParam(aMsg, NPVARIANT_TO_DOUBLE(aParam));
547 return;
550 if (NPVARIANT_IS_STRING(aParam)) {
551 aMsg->WriteInt(5);
552 WriteParam(aMsg, NPVARIANT_TO_STRING(aParam));
553 return;
556 NS_ERROR("Unsupported type!");
559 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
561 int type;
562 if (!aMsg->ReadInt(aIter, &type)) {
563 return false;
566 switch (type) {
567 case 0:
568 VOID_TO_NPVARIANT(*aResult);
569 return true;
571 case 1:
572 NULL_TO_NPVARIANT(*aResult);
573 return true;
575 case 2: {
576 bool value;
577 if (ReadParam(aMsg, aIter, &value)) {
578 BOOLEAN_TO_NPVARIANT(value, *aResult);
579 return true;
581 } break;
583 case 3: {
584 int32 value;
585 if (ReadParam(aMsg, aIter, &value)) {
586 INT32_TO_NPVARIANT(value, *aResult);
587 return true;
589 } break;
591 case 4: {
592 double value;
593 if (ReadParam(aMsg, aIter, &value)) {
594 DOUBLE_TO_NPVARIANT(value, *aResult);
595 return true;
597 } break;
599 case 5: {
600 NPString value;
601 if (ReadParam(aMsg, aIter, &value)) {
602 STRINGN_TO_NPVARIANT(value.UTF8Characters, value.UTF8Length,
603 *aResult);
604 return true;
606 } break;
608 default:
609 NS_ERROR("Unsupported type!");
612 return false;
615 static void Log(const paramType& aParam, std::wstring* aLog)
617 if (NPVARIANT_IS_VOID(aParam)) {
618 aLog->append(L"[void]");
619 return;
622 if (NPVARIANT_IS_NULL(aParam)) {
623 aLog->append(L"[null]");
624 return;
627 if (NPVARIANT_IS_BOOLEAN(aParam)) {
628 LogParam(NPVARIANT_TO_BOOLEAN(aParam), aLog);
629 return;
632 if (NPVARIANT_IS_INT32(aParam)) {
633 LogParam(NPVARIANT_TO_INT32(aParam), aLog);
634 return;
637 if (NPVARIANT_IS_DOUBLE(aParam)) {
638 LogParam(NPVARIANT_TO_DOUBLE(aParam), aLog);
639 return;
642 if (NPVARIANT_IS_STRING(aParam)) {
643 LogParam(NPVARIANT_TO_STRING(aParam), aLog);
644 return;
647 NS_ERROR("Unsupported type!");
651 template<>
652 struct ParamTraits<mozilla::void_t>
654 typedef mozilla::void_t paramType;
655 static void Write(Message* aMsg, const paramType& aParam) { }
656 static bool
657 Read(const Message* aMsg, void** aIter, paramType* aResult)
659 *aResult = paramType();
660 return true;
664 template<>
665 struct ParamTraits<mozilla::null_t>
667 typedef mozilla::null_t paramType;
668 static void Write(Message* aMsg, const paramType& aParam) { }
669 static bool
670 Read(const Message* aMsg, void** aIter, paramType* aResult)
672 *aResult = paramType();
673 return true;
677 template <>
678 struct ParamTraits<mozilla::plugins::IPCByteRange>
680 typedef mozilla::plugins::IPCByteRange paramType;
682 static void Write(Message* aMsg, const paramType& aParam)
684 WriteParam(aMsg, aParam.offset);
685 WriteParam(aMsg, aParam.length);
688 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
690 paramType p;
691 if (ReadParam(aMsg, aIter, &p.offset) &&
692 ReadParam(aMsg, aIter, &p.length)) {
693 *aResult = p;
694 return true;
696 return false;
700 template <>
701 struct ParamTraits<NPNVariable>
703 typedef NPNVariable paramType;
705 static void Write(Message* aMsg, const paramType& aParam)
707 WriteParam(aMsg, int(aParam));
710 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
712 int intval;
713 if (ReadParam(aMsg, aIter, &intval)) {
714 *aResult = paramType(intval);
715 return true;
717 return false;
721 template<>
722 struct ParamTraits<NPNURLVariable>
724 typedef NPNURLVariable paramType;
726 static void Write(Message* aMsg, const paramType& aParam)
728 WriteParam(aMsg, int(aParam));
731 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
733 int intval;
734 if (ReadParam(aMsg, aIter, &intval)) {
735 switch (intval) {
736 case NPNURLVCookie:
737 case NPNURLVProxy:
738 *aResult = paramType(intval);
739 return true;
742 return false;
747 template<>
748 struct ParamTraits<NPCoordinateSpace>
750 typedef NPCoordinateSpace paramType;
752 static void Write(Message* aMsg, const paramType& aParam)
754 WriteParam(aMsg, int32(aParam));
757 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
759 int32 intval;
760 if (ReadParam(aMsg, aIter, &intval)) {
761 switch (intval) {
762 case NPCoordinateSpacePlugin:
763 case NPCoordinateSpaceWindow:
764 case NPCoordinateSpaceFlippedWindow:
765 case NPCoordinateSpaceScreen:
766 case NPCoordinateSpaceFlippedScreen:
767 *aResult = paramType(intval);
768 return true;
771 return false;
775 } /* namespace IPC */
778 // Serializing NPEvents is completely platform-specific and can be rather
779 // intricate depending on the platform. So for readability we split it
780 // into separate files and have the only macro crud live here.
782 // NB: these guards are based on those where struct NPEvent is defined
783 // in npapi.h. They should be kept in sync.
784 #if defined(XP_MACOSX)
785 # include "mozilla/plugins/NPEventOSX.h"
786 #elif defined(XP_WIN)
787 # include "mozilla/plugins/NPEventWindows.h"
788 #elif defined(XP_OS2)
789 # error Sorry, OS/2 is not supported
790 #elif defined(XP_UNIX) && defined(MOZ_X11)
791 # include "mozilla/plugins/NPEventX11.h"
792 #else
793 # error Unsupported platform
794 #endif
796 #endif /* DOM_PLUGINS_PLUGINMESSAGEUTILS_H */