CLOSED TREE: TraceMonkey merge head. (a=blockers)
[mozilla-central.git] / dom / plugins / PluginMessageUtils.h
blob32211c7ea8925467702dda60e994f4d9a982e17b
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 {
61 namespace plugins {
63 enum ScriptableObjectType
65 LocalObject,
66 Proxy
69 mozilla::ipc::RPCChannel::RacyRPCPolicy
70 MediateRace(const mozilla::ipc::RPCChannel::Message& parent,
71 const mozilla::ipc::RPCChannel::Message& child);
73 std::string
74 MungePluginDsoPath(const std::string& path);
75 std::string
76 UnmungePluginDsoPath(const std::string& munged);
78 extern PRLogModuleInfo* gPluginLog;
80 #if defined(_MSC_VER)
81 #define FULLFUNCTION __FUNCSIG__
82 #elif (__GNUC__ >= 4)
83 #define FULLFUNCTION __PRETTY_FUNCTION__
84 #else
85 #define FULLFUNCTION __FUNCTION__
86 #endif
88 #define PLUGIN_LOG_DEBUG(args) PR_LOG(gPluginLog, PR_LOG_DEBUG, args)
89 #define PLUGIN_LOG_DEBUG_FUNCTION PR_LOG(gPluginLog, PR_LOG_DEBUG, ("%s", FULLFUNCTION))
90 #define PLUGIN_LOG_DEBUG_METHOD PR_LOG(gPluginLog, PR_LOG_DEBUG, ("%s [%p]", FULLFUNCTION, (void*) this))
92 /**
93 * This is NPByteRange without the linked list.
95 struct IPCByteRange
97 int32_t offset;
98 uint32_t length;
99 };
101 typedef std::vector<IPCByteRange> IPCByteRanges;
103 typedef nsCString Buffer;
105 struct NPRemoteWindow
107 unsigned long window;
108 int32_t x;
109 int32_t y;
110 uint32_t width;
111 uint32_t height;
112 NPRect clipRect;
113 NPWindowType type;
114 #if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
115 VisualID visualID;
116 Colormap colormap;
117 #endif /* XP_UNIX */
118 #if defined(XP_WIN)
119 base::SharedMemoryHandle surfaceHandle;
120 #endif
123 #ifdef XP_WIN
124 typedef HWND NativeWindowHandle;
125 #elif defined(MOZ_X11)
126 typedef XID NativeWindowHandle;
127 #elif defined(XP_MACOSX) || defined(ANDROID)
128 typedef intptr_t NativeWindowHandle; // never actually used, will always be 0
129 #else
130 #error Need NativeWindowHandle for this platform
131 #endif
133 #ifdef XP_WIN
134 typedef base::SharedMemoryHandle WindowsSharedMemoryHandle;
135 #else
136 typedef mozilla::null_t WindowsSharedMemoryHandle;
137 #endif
139 #ifdef MOZ_CRASHREPORTER
140 typedef CrashReporter::ThreadId NativeThreadId;
141 #else
142 // unused in this case
143 typedef int32 NativeThreadId;
144 #endif
146 // XXX maybe not the best place for these. better one?
148 #define VARSTR(v_) case v_: return #v_
149 inline const char* const
150 NPPVariableToString(NPPVariable aVar)
152 switch (aVar) {
153 VARSTR(NPPVpluginNameString);
154 VARSTR(NPPVpluginDescriptionString);
155 VARSTR(NPPVpluginWindowBool);
156 VARSTR(NPPVpluginTransparentBool);
157 VARSTR(NPPVjavaClass);
158 VARSTR(NPPVpluginWindowSize);
159 VARSTR(NPPVpluginTimerInterval);
161 VARSTR(NPPVpluginScriptableInstance);
162 VARSTR(NPPVpluginScriptableIID);
164 VARSTR(NPPVjavascriptPushCallerBool);
166 VARSTR(NPPVpluginKeepLibraryInMemory);
167 VARSTR(NPPVpluginNeedsXEmbed);
169 VARSTR(NPPVpluginScriptableNPObject);
171 VARSTR(NPPVformValue);
173 VARSTR(NPPVpluginUrlRequestsDisplayedBool);
175 VARSTR(NPPVpluginWantsAllNetworkStreams);
177 #ifdef XP_MACOSX
178 VARSTR(NPPVpluginDrawingModel);
179 VARSTR(NPPVpluginEventModel);
180 #endif
182 default: return "???";
186 inline const char*
187 NPNVariableToString(NPNVariable aVar)
189 switch(aVar) {
190 VARSTR(NPNVxDisplay);
191 VARSTR(NPNVxtAppContext);
192 VARSTR(NPNVnetscapeWindow);
193 VARSTR(NPNVjavascriptEnabledBool);
194 VARSTR(NPNVasdEnabledBool);
195 VARSTR(NPNVisOfflineBool);
197 VARSTR(NPNVserviceManager);
198 VARSTR(NPNVDOMElement);
199 VARSTR(NPNVDOMWindow);
200 VARSTR(NPNVToolkit);
201 VARSTR(NPNVSupportsXEmbedBool);
203 VARSTR(NPNVWindowNPObject);
205 VARSTR(NPNVPluginElementNPObject);
207 VARSTR(NPNVSupportsWindowless);
209 VARSTR(NPNVprivateModeBool);
211 default: return "???";
214 #undef VARSTR
216 inline bool IsPluginThread()
218 MessageLoop* loop = MessageLoop::current();
219 if (!loop)
220 return false;
221 return (loop->type() == MessageLoop::TYPE_UI);
224 inline void AssertPluginThread()
226 NS_ASSERTION(IsPluginThread(), "Should be on the plugin's main thread!");
229 #define ENSURE_PLUGIN_THREAD(retval) \
230 PR_BEGIN_MACRO \
231 if (!IsPluginThread()) { \
232 NS_WARNING("Not running on the plugin's main thread!"); \
233 return (retval); \
235 PR_END_MACRO
237 #define ENSURE_PLUGIN_THREAD_VOID() \
238 PR_BEGIN_MACRO \
239 if (!IsPluginThread()) { \
240 NS_WARNING("Not running on the plugin's main thread!"); \
241 return; \
243 PR_END_MACRO
245 void DeferNPObjectLastRelease(const NPNetscapeFuncs* f, NPObject* o);
246 void DeferNPVariantLastRelease(const NPNetscapeFuncs* f, NPVariant* v);
248 // in NPAPI, char* == NULL is sometimes meaningful. the following is
249 // helper code for dealing with nullable nsCString's
250 inline nsCString
251 NullableString(const char* aString)
253 if (!aString) {
254 nsCString str;
255 str.SetIsVoid(PR_TRUE);
256 return str;
258 return nsCString(aString);
261 inline const char*
262 NullableStringGet(const nsCString& str)
264 if (str.IsVoid())
265 return NULL;
267 return str.get();
270 struct DeletingObjectEntry : public nsPtrHashKey<NPObject>
272 DeletingObjectEntry(const NPObject* key)
273 : nsPtrHashKey<NPObject>(key)
274 , mDeleted(false)
277 bool mDeleted;
280 #ifdef XP_WIN
281 // The private event used for double-pass widgetless plugin rendering.
282 UINT DoublePassRenderingEvent();
283 #endif
285 } /* namespace plugins */
287 } /* namespace mozilla */
289 namespace IPC {
291 template <>
292 struct ParamTraits<NPRect>
294 typedef NPRect paramType;
296 static void Write(Message* aMsg, const paramType& aParam)
298 WriteParam(aMsg, aParam.top);
299 WriteParam(aMsg, aParam.left);
300 WriteParam(aMsg, aParam.bottom);
301 WriteParam(aMsg, aParam.right);
304 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
306 uint16_t top, left, bottom, right;
307 if (ReadParam(aMsg, aIter, &top) &&
308 ReadParam(aMsg, aIter, &left) &&
309 ReadParam(aMsg, aIter, &bottom) &&
310 ReadParam(aMsg, aIter, &right)) {
311 aResult->top = top;
312 aResult->left = left;
313 aResult->bottom = bottom;
314 aResult->right = right;
315 return true;
317 return false;
320 static void Log(const paramType& aParam, std::wstring* aLog)
322 aLog->append(StringPrintf(L"[%u, %u, %u, %u]", aParam.top, aParam.left,
323 aParam.bottom, aParam.right));
327 template <>
328 struct ParamTraits<NPWindowType>
330 typedef NPWindowType paramType;
332 static void Write(Message* aMsg, const paramType& aParam)
334 aMsg->WriteInt16(int16(aParam));
337 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
339 int16 result;
340 if (aMsg->ReadInt16(aIter, &result)) {
341 *aResult = paramType(result);
342 return true;
344 return false;
347 static void Log(const paramType& aParam, std::wstring* aLog)
349 aLog->append(StringPrintf(L"%d", int16(aParam)));
353 template <>
354 struct ParamTraits<mozilla::plugins::NPRemoteWindow>
356 typedef mozilla::plugins::NPRemoteWindow paramType;
358 static void Write(Message* aMsg, const paramType& aParam)
360 aMsg->WriteULong(aParam.window);
361 WriteParam(aMsg, aParam.x);
362 WriteParam(aMsg, aParam.y);
363 WriteParam(aMsg, aParam.width);
364 WriteParam(aMsg, aParam.height);
365 WriteParam(aMsg, aParam.clipRect);
366 WriteParam(aMsg, aParam.type);
367 #if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
368 aMsg->WriteULong(aParam.visualID);
369 aMsg->WriteULong(aParam.colormap);
370 #endif
371 #if defined(XP_WIN)
372 WriteParam(aMsg, aParam.surfaceHandle);
373 #endif
376 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
378 unsigned long window;
379 int32_t x, y;
380 uint32_t width, height;
381 NPRect clipRect;
382 NPWindowType type;
383 if (!(aMsg->ReadULong(aIter, &window) &&
384 ReadParam(aMsg, aIter, &x) &&
385 ReadParam(aMsg, aIter, &y) &&
386 ReadParam(aMsg, aIter, &width) &&
387 ReadParam(aMsg, aIter, &height) &&
388 ReadParam(aMsg, aIter, &clipRect) &&
389 ReadParam(aMsg, aIter, &type)))
390 return false;
392 #if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
393 unsigned long visualID;
394 unsigned long colormap;
395 if (!(aMsg->ReadULong(aIter, &visualID) &&
396 aMsg->ReadULong(aIter, &colormap)))
397 return false;
398 #endif
400 #if defined(XP_WIN)
401 base::SharedMemoryHandle surfaceHandle;
402 if (!ReadParam(aMsg, aIter, &surfaceHandle))
403 return false;
404 #endif
406 aResult->window = window;
407 aResult->x = x;
408 aResult->y = y;
409 aResult->width = width;
410 aResult->height = height;
411 aResult->clipRect = clipRect;
412 aResult->type = type;
413 #if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
414 aResult->visualID = visualID;
415 aResult->colormap = colormap;
416 #endif
417 #if defined(XP_WIN)
418 aResult->surfaceHandle = surfaceHandle;
419 #endif
420 return true;
423 static void Log(const paramType& aParam, std::wstring* aLog)
425 aLog->append(StringPrintf(L"[%u, %d, %d, %u, %u, %d",
426 (unsigned long)aParam.window,
427 aParam.x, aParam.y, aParam.width,
428 aParam.height, (long)aParam.type));
432 template <>
433 struct ParamTraits<NPString>
435 typedef NPString paramType;
437 static void Write(Message* aMsg, const paramType& aParam)
439 WriteParam(aMsg, aParam.UTF8Length);
440 aMsg->WriteBytes(aParam.UTF8Characters,
441 aParam.UTF8Length * sizeof(NPUTF8));
444 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
446 if (ReadParam(aMsg, aIter, &aResult->UTF8Length)) {
447 int byteCount = aResult->UTF8Length * sizeof(NPUTF8);
448 if (!byteCount) {
449 aResult->UTF8Characters = "\0";
450 return true;
453 const char* messageBuffer = nsnull;
454 nsAutoArrayPtr<char> newBuffer(new char[byteCount]);
455 if (newBuffer && aMsg->ReadBytes(aIter, &messageBuffer, byteCount )) {
456 memcpy((void*)messageBuffer, newBuffer.get(), byteCount);
457 aResult->UTF8Characters = newBuffer.forget();
458 return true;
461 return false;
464 static void Log(const paramType& aParam, std::wstring* aLog)
466 aLog->append(StringPrintf(L"%s", aParam.UTF8Characters));
470 #ifdef XP_MACOSX
471 template <>
472 struct ParamTraits<NPNSString*>
474 typedef NPNSString* paramType;
476 // Empty string writes a length of 0 and no buffer.
477 // We don't write a NULL terminating character in buffers.
478 static void Write(Message* aMsg, const paramType& aParam)
480 CFStringRef cfString = (CFStringRef)aParam;
482 // Write true if we have a string, false represents NULL.
483 aMsg->WriteBool(!!cfString);
484 if (!cfString) {
485 return;
488 long length = ::CFStringGetLength(cfString);
489 WriteParam(aMsg, length);
490 if (length == 0) {
491 return;
494 // Attempt to get characters without any allocation/conversion.
495 if (::CFStringGetCharactersPtr(cfString)) {
496 aMsg->WriteBytes(::CFStringGetCharactersPtr(cfString), length * sizeof(UniChar));
497 } else {
498 UniChar *buffer = (UniChar*)moz_xmalloc(length * sizeof(UniChar));
499 ::CFStringGetCharacters(cfString, ::CFRangeMake(0, length), buffer);
500 aMsg->WriteBytes(buffer, length * sizeof(UniChar));
501 free(buffer);
505 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
507 bool haveString = false;
508 if (!aMsg->ReadBool(aIter, &haveString)) {
509 return false;
511 if (!haveString) {
512 *aResult = NULL;
513 return true;
516 long length;
517 if (!ReadParam(aMsg, aIter, &length)) {
518 return false;
521 UniChar* buffer = nsnull;
522 if (length != 0) {
523 if (!aMsg->ReadBytes(aIter, (const char**)&buffer, length * sizeof(UniChar)) ||
524 !buffer) {
525 return false;
529 *aResult = (NPNSString*)::CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8*)buffer,
530 length * sizeof(UniChar),
531 kCFStringEncodingUTF16, false);
532 if (!*aResult) {
533 return false;
536 return true;
539 #endif
541 template <>
542 struct ParamTraits<NPVariant>
544 typedef NPVariant paramType;
546 static void Write(Message* aMsg, const paramType& aParam)
548 if (NPVARIANT_IS_VOID(aParam)) {
549 aMsg->WriteInt(0);
550 return;
553 if (NPVARIANT_IS_NULL(aParam)) {
554 aMsg->WriteInt(1);
555 return;
558 if (NPVARIANT_IS_BOOLEAN(aParam)) {
559 aMsg->WriteInt(2);
560 WriteParam(aMsg, NPVARIANT_TO_BOOLEAN(aParam));
561 return;
564 if (NPVARIANT_IS_INT32(aParam)) {
565 aMsg->WriteInt(3);
566 WriteParam(aMsg, NPVARIANT_TO_INT32(aParam));
567 return;
570 if (NPVARIANT_IS_DOUBLE(aParam)) {
571 aMsg->WriteInt(4);
572 WriteParam(aMsg, NPVARIANT_TO_DOUBLE(aParam));
573 return;
576 if (NPVARIANT_IS_STRING(aParam)) {
577 aMsg->WriteInt(5);
578 WriteParam(aMsg, NPVARIANT_TO_STRING(aParam));
579 return;
582 NS_ERROR("Unsupported type!");
585 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
587 int type;
588 if (!aMsg->ReadInt(aIter, &type)) {
589 return false;
592 switch (type) {
593 case 0:
594 VOID_TO_NPVARIANT(*aResult);
595 return true;
597 case 1:
598 NULL_TO_NPVARIANT(*aResult);
599 return true;
601 case 2: {
602 bool value;
603 if (ReadParam(aMsg, aIter, &value)) {
604 BOOLEAN_TO_NPVARIANT(value, *aResult);
605 return true;
607 } break;
609 case 3: {
610 int32 value;
611 if (ReadParam(aMsg, aIter, &value)) {
612 INT32_TO_NPVARIANT(value, *aResult);
613 return true;
615 } break;
617 case 4: {
618 double value;
619 if (ReadParam(aMsg, aIter, &value)) {
620 DOUBLE_TO_NPVARIANT(value, *aResult);
621 return true;
623 } break;
625 case 5: {
626 NPString value;
627 if (ReadParam(aMsg, aIter, &value)) {
628 STRINGN_TO_NPVARIANT(value.UTF8Characters, value.UTF8Length,
629 *aResult);
630 return true;
632 } break;
634 default:
635 NS_ERROR("Unsupported type!");
638 return false;
641 static void Log(const paramType& aParam, std::wstring* aLog)
643 if (NPVARIANT_IS_VOID(aParam)) {
644 aLog->append(L"[void]");
645 return;
648 if (NPVARIANT_IS_NULL(aParam)) {
649 aLog->append(L"[null]");
650 return;
653 if (NPVARIANT_IS_BOOLEAN(aParam)) {
654 LogParam(NPVARIANT_TO_BOOLEAN(aParam), aLog);
655 return;
658 if (NPVARIANT_IS_INT32(aParam)) {
659 LogParam(NPVARIANT_TO_INT32(aParam), aLog);
660 return;
663 if (NPVARIANT_IS_DOUBLE(aParam)) {
664 LogParam(NPVARIANT_TO_DOUBLE(aParam), aLog);
665 return;
668 if (NPVARIANT_IS_STRING(aParam)) {
669 LogParam(NPVARIANT_TO_STRING(aParam), aLog);
670 return;
673 NS_ERROR("Unsupported type!");
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 #elif defined(ANDROID)
793 # include "mozilla/plugins/NPEventAndroid.h"
794 #else
795 # error Unsupported platform
796 #endif
798 #endif /* DOM_PLUGINS_PLUGINMESSAGEUTILS_H */