1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
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
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.
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 #ifdef MOZ_WIDGET_GTK2
42 #include "PluginUtilsOSX.h"
43 #include "PluginInterposeOSX.h"
46 #include <QtCore/QCoreApplication>
47 #include <QtCore/QEventLoop>
50 #include "base/process_util.h"
52 #include "mozilla/unused.h"
53 #include "mozilla/ipc/SyncChannel.h"
54 #include "mozilla/plugins/PluginModuleParent.h"
55 #include "mozilla/plugins/BrowserStreamParent.h"
56 #include "PluginIdentifierParent.h"
58 #include "nsAutoPtr.h"
59 #include "nsContentUtils.h"
61 #ifdef MOZ_CRASHREPORTER
62 #include "nsExceptionHandler.h"
64 #include "nsNPAPIPlugin.h"
66 using base::KillProcess
;
68 using mozilla::PluginLibrary
;
69 using mozilla::ipc::SyncChannel
;
71 using namespace mozilla::plugins
;
73 static const char kTimeoutPref
[] = "dom.ipc.plugins.timeoutSecs";
74 static const char kLaunchTimeoutPref
[] = "dom.ipc.plugins.processLaunchTimeoutSecs";
77 struct RunnableMethodTraits
<mozilla::plugins::PluginModuleParent
>
79 typedef mozilla::plugins::PluginModuleParent Class
;
80 static void RetainCallee(Class
* obj
) { }
81 static void ReleaseCallee(Class
* obj
) { }
86 PluginModuleParent::LoadModule(const char* aFilePath
)
88 PLUGIN_LOG_DEBUG_FUNCTION
;
90 PRInt32 prefSecs
= nsContentUtils::GetIntPref(kLaunchTimeoutPref
, 0);
92 // Block on the child process being launched and initialized.
93 nsAutoPtr
<PluginModuleParent
> parent(new PluginModuleParent(aFilePath
));
94 bool launched
= parent
->mSubprocess
->Launch(prefSecs
* 1000);
96 // Need to set this so the destructor doesn't complain.
97 parent
->mShutdown
= true;
100 parent
->Open(parent
->mSubprocess
->GetChannel(),
101 parent
->mSubprocess
->GetChildProcessHandle());
103 TimeoutChanged(kTimeoutPref
, parent
);
104 return parent
.forget();
108 PluginModuleParent::PluginModuleParent(const char* aFilePath
)
109 : mSubprocess(new PluginProcessParent(aFilePath
))
114 , mProcessStartTime(time(NULL
))
117 NS_ASSERTION(mSubprocess
, "Out of memory!");
119 if (!mIdentifiers
.Init()) {
120 NS_ERROR("Out of memory");
123 nsContentUtils::RegisterPrefCallback(kTimeoutPref
, TimeoutChanged
, this);
126 PluginModuleParent::~PluginModuleParent()
128 NS_ASSERTION(OkToCleanup(), "unsafe destruction");
137 NS_WARNING("Plugin host deleted the module without shutting down.");
141 NS_ASSERTION(mShutdown
, "NP_Shutdown didn't");
144 mSubprocess
->Delete();
145 mSubprocess
= nsnull
;
148 nsContentUtils::UnregisterPrefCallback(kTimeoutPref
, TimeoutChanged
, this);
151 #ifdef MOZ_CRASHREPORTER
153 PluginModuleParent::WritePluginExtraDataForMinidump(const nsAString
& id
)
155 typedef nsDependentCString CS
;
157 CrashReporter::AnnotationTable notes
;
161 notes
.Put(CS("ProcessType"), CS("plugin"));
164 sprintf(startTime
, "%lld", static_cast<PRInt64
>(mProcessStartTime
));
165 notes
.Put(CS("StartupTime"), CS(startTime
));
167 // Get the plugin filename, try to get just the file leafname
168 const std::string
& pluginFile
= mSubprocess
->GetPluginFilePath();
169 size_t filePos
= pluginFile
.rfind(FILE_PATH_SEPARATOR
);
170 if (filePos
== std::string::npos
)
174 notes
.Put(CS("PluginFilename"), CS(pluginFile
.substr(filePos
).c_str()));
176 //TODO: add plugin name and version: bug 539841
177 // (as PluginName, PluginVersion)
178 notes
.Put(CS("PluginName"), CS(""));
179 notes
.Put(CS("PluginVersion"), CS(""));
181 if (!mCrashNotes
.IsEmpty())
182 notes
.Put(CS("Notes"), CS(mCrashNotes
.get()));
184 if (!mHangID
.IsEmpty())
185 notes
.Put(CS("HangID"), NS_ConvertUTF16toUTF8(mHangID
));
187 if (!CrashReporter::AppendExtraData(id
, notes
))
188 NS_WARNING("problem appending plugin data to .extra");
192 PluginModuleParent::WriteExtraDataForHang()
194 // this writes HangID
195 WritePluginExtraDataForMinidump(mPluginDumpID
);
197 CrashReporter::AnnotationTable notes
;
201 notes
.Put(nsDependentCString("HangID"), NS_ConvertUTF16toUTF8(mHangID
));
202 if (!CrashReporter::AppendExtraData(mBrowserDumpID
, notes
))
203 NS_WARNING("problem appending browser data to .extra");
205 #endif // MOZ_CRASHREPORTER
208 PluginModuleParent::RecvAppendNotesToCrashReport(const nsCString
& aNotes
)
210 mCrashNotes
.Append(aNotes
);
215 PluginModuleParent::TimeoutChanged(const char* aPref
, void* aModule
)
217 NS_ASSERTION(NS_IsMainThread(), "Wrong thead!");
218 NS_ABORT_IF_FALSE(!strcmp(aPref
, kTimeoutPref
),
219 "unexpected pref callback");
221 PRInt32 timeoutSecs
= nsContentUtils::GetIntPref(kTimeoutPref
, 0);
222 int32 timeoutMs
= (timeoutSecs
> 0) ? (1000 * timeoutSecs
) :
223 SyncChannel::kNoTimeout
;
225 static_cast<PluginModuleParent
*>(aModule
)->SetReplyTimeoutMs(timeoutMs
);
230 PluginModuleParent::CleanupFromTimeout()
237 PluginModuleParent::ShouldContinueFromReplyTimeout()
239 #ifdef MOZ_CRASHREPORTER
240 nsCOMPtr
<nsILocalFile
> pluginDump
;
241 nsCOMPtr
<nsILocalFile
> browserDump
;
242 CrashReporter::ProcessHandle child
;
244 child
= mSubprocess
->GetChildTask();
246 child
= OtherProcess();
248 if (CrashReporter::CreatePairedMinidumps(child
,
251 getter_AddRefs(pluginDump
),
252 getter_AddRefs(browserDump
)) &&
253 CrashReporter::GetIDFromMinidump(pluginDump
, mPluginDumpID
) &&
254 CrashReporter::GetIDFromMinidump(browserDump
, mBrowserDumpID
)) {
257 ("generated paired browser/plugin minidumps: %s/%s (ID=%s)",
258 NS_ConvertUTF16toUTF8(mBrowserDumpID
).get(),
259 NS_ConvertUTF16toUTF8(mPluginDumpID
).get(),
260 NS_ConvertUTF16toUTF8(mHangID
).get()));
263 NS_WARNING("failed to capture paired minidumps from hang");
267 // this must run before the error notification from the channel,
269 MessageLoop::current()->PostTask(
271 mTaskFactory
.NewRunnableMethod(
272 &PluginModuleParent::CleanupFromTimeout
));
274 if (!KillProcess(OtherProcess(), 1, false))
275 NS_WARNING("failed to kill subprocess!");
281 PluginModuleParent::ActorDestroy(ActorDestroyReason why
)
284 case AbnormalShutdown
: {
285 #ifdef MOZ_CRASHREPORTER
286 nsCOMPtr
<nsILocalFile
> pluginDump
;
287 if (TakeMinidump(getter_AddRefs(pluginDump
)) &&
288 CrashReporter::GetIDFromMinidump(pluginDump
, mPluginDumpID
)) {
289 PLUGIN_LOG_DEBUG(("got child minidump: %s",
290 NS_ConvertUTF16toUTF8(mPluginDumpID
).get()));
291 WritePluginExtraDataForMinidump(mPluginDumpID
);
293 else if (!mPluginDumpID
.IsEmpty() && !mBrowserDumpID
.IsEmpty()) {
294 WriteExtraDataForHang();
297 NS_WARNING("[PluginModuleParent::ActorDestroy] abnormal shutdown without minidump!");
302 // Defer the PluginCrashed method so that we don't re-enter
303 // and potentially modify the actor child list while enumerating it.
305 MessageLoop::current()->PostTask(
307 mTaskFactory
.NewRunnableMethod(
308 &PluginModuleParent::NotifyPluginCrashed
));
316 NS_ERROR("Unexpected shutdown reason for toplevel actor.");
321 PluginModuleParent::NotifyPluginCrashed()
323 if (!OkToCleanup()) {
324 // there's still plugin code on the C++ stack. try again
325 MessageLoop::current()->PostDelayedTask(
327 mTaskFactory
.NewRunnableMethod(
328 &PluginModuleParent::NotifyPluginCrashed
), 10);
333 mPlugin
->PluginCrashed(mPluginDumpID
, mBrowserDumpID
);
336 PPluginIdentifierParent
*
337 PluginModuleParent::AllocPPluginIdentifier(const nsCString
& aString
,
340 NPIdentifier npident
= aString
.IsVoid() ?
341 mozilla::plugins::parent::_getintidentifier(aInt
) :
342 mozilla::plugins::parent::_getstringidentifier(aString
.get());
345 NS_WARNING("Failed to get identifier!");
349 PluginIdentifierParent
* ident
= new PluginIdentifierParent(npident
);
350 mIdentifiers
.Put(npident
, ident
);
355 PluginModuleParent::DeallocPPluginIdentifier(PPluginIdentifierParent
* aActor
)
361 PPluginInstanceParent
*
362 PluginModuleParent::AllocPPluginInstance(const nsCString
& aMimeType
,
363 const uint16_t& aMode
,
364 const InfallibleTArray
<nsCString
>& aNames
,
365 const InfallibleTArray
<nsCString
>& aValues
,
368 NS_ERROR("Not reachable!");
373 PluginModuleParent::DeallocPPluginInstance(PPluginInstanceParent
* aActor
)
375 PLUGIN_LOG_DEBUG_METHOD
;
381 PluginModuleParent::SetPluginFuncs(NPPluginFuncs
* aFuncs
)
383 aFuncs
->version
= (NP_VERSION_MAJOR
<< 8) | NP_VERSION_MINOR
;
384 aFuncs
->javaClass
= nsnull
;
386 aFuncs
->newp
= nsnull
; // Gecko should always call this through a PluginLibrary object
387 aFuncs
->destroy
= NPP_Destroy
;
388 aFuncs
->setwindow
= NPP_SetWindow
;
389 aFuncs
->newstream
= NPP_NewStream
;
390 aFuncs
->destroystream
= NPP_DestroyStream
;
391 aFuncs
->asfile
= NPP_StreamAsFile
;
392 aFuncs
->writeready
= NPP_WriteReady
;
393 aFuncs
->write
= NPP_Write
;
394 aFuncs
->print
= NPP_Print
;
395 aFuncs
->event
= NPP_HandleEvent
;
396 aFuncs
->urlnotify
= NPP_URLNotify
;
397 aFuncs
->getvalue
= NPP_GetValue
;
398 aFuncs
->setvalue
= NPP_SetValue
;
402 PluginModuleParent::NPP_Destroy(NPP instance
,
403 NPSavedData
** /*saved*/)
406 // (1) send a "destroy" message to the child
407 // (2) the child shuts down its instance
408 // (3) remove both parent and child IDs from map
410 PLUGIN_LOG_DEBUG_FUNCTION
;
412 PluginInstanceParent
* parentInstance
=
413 static_cast<PluginInstanceParent
*>(instance
->pdata
);
416 return NPERR_NO_ERROR
;
418 NPError retval
= parentInstance
->Destroy();
419 instance
->pdata
= nsnull
;
421 unused
<< PluginInstanceParent::Call__delete__(parentInstance
);
426 PluginModuleParent::NPP_NewStream(NPP instance
, NPMIMEType type
,
427 NPStream
* stream
, NPBool seekable
,
430 PluginInstanceParent
* i
= InstCast(instance
);
432 return NPERR_GENERIC_ERROR
;
434 return i
->NPP_NewStream(type
, stream
, seekable
,
439 PluginModuleParent::NPP_SetWindow(NPP instance
, NPWindow
* window
)
441 PluginInstanceParent
* i
= InstCast(instance
);
443 return NPERR_GENERIC_ERROR
;
445 return i
->NPP_SetWindow(window
);
449 PluginModuleParent::NPP_DestroyStream(NPP instance
,
453 PluginInstanceParent
* i
= InstCast(instance
);
455 return NPERR_GENERIC_ERROR
;
457 return i
->NPP_DestroyStream(stream
, reason
);
461 PluginModuleParent::NPP_WriteReady(NPP instance
,
464 BrowserStreamParent
* s
= StreamCast(instance
, stream
);
468 return s
->WriteReady();
472 PluginModuleParent::NPP_Write(NPP instance
,
478 BrowserStreamParent
* s
= StreamCast(instance
, stream
);
482 return s
->Write(offset
, len
, buffer
);
486 PluginModuleParent::NPP_StreamAsFile(NPP instance
,
490 BrowserStreamParent
* s
= StreamCast(instance
, stream
);
494 s
->StreamAsFile(fname
);
498 PluginModuleParent::NPP_Print(NPP instance
, NPPrint
* platformPrint
)
500 PluginInstanceParent
* i
= InstCast(instance
);
502 i
->NPP_Print(platformPrint
);
506 PluginModuleParent::NPP_HandleEvent(NPP instance
, void* event
)
508 PluginInstanceParent
* i
= InstCast(instance
);
512 return i
->NPP_HandleEvent(event
);
516 PluginModuleParent::NPP_URLNotify(NPP instance
, const char* url
,
517 NPReason reason
, void* notifyData
)
519 PluginInstanceParent
* i
= InstCast(instance
);
523 i
->NPP_URLNotify(url
, reason
, notifyData
);
527 PluginModuleParent::NPP_GetValue(NPP instance
,
528 NPPVariable variable
, void *ret_value
)
530 PluginInstanceParent
* i
= InstCast(instance
);
532 return NPERR_GENERIC_ERROR
;
534 return i
->NPP_GetValue(variable
, ret_value
);
538 PluginModuleParent::NPP_SetValue(NPP instance
, NPNVariable variable
,
541 PluginInstanceParent
* i
= InstCast(instance
);
543 return NPERR_GENERIC_ERROR
;
545 return i
->NPP_SetValue(variable
, value
);
549 PluginModuleParent::RecvBackUpXResources(const FileDescriptor
& aXSocketFd
)
552 NS_RUNTIMEABORT("This message only makes sense on X11 platforms");
554 NS_ABORT_IF_FALSE(0 > mPluginXSocketFdDup
.mFd
,
555 "Already backed up X resources??");
556 mPluginXSocketFdDup
.mFd
= aXSocketFd
.fd
;
562 PluginModuleParent::AnswerNPN_UserAgent(nsCString
* userAgent
)
564 *userAgent
= NullableString(mNPNIface
->uagent(nsnull
));
568 PPluginIdentifierParent
*
569 PluginModuleParent::GetIdentifierForNPIdentifier(NPIdentifier aIdentifier
)
571 PluginIdentifierParent
* ident
;
572 if (!mIdentifiers
.Get(aIdentifier
, &ident
)) {
575 if (mozilla::plugins::parent::_identifierisstring(aIdentifier
)) {
577 mozilla::plugins::parent::_utf8fromidentifier(aIdentifier
);
584 intval
= mozilla::plugins::parent::_intfromidentifier(aIdentifier
);
585 string
.SetIsVoid(PR_TRUE
);
587 ident
= new PluginIdentifierParent(aIdentifier
);
588 if (!SendPPluginIdentifierConstructor(ident
, string
, intval
))
591 mIdentifiers
.Put(aIdentifier
, ident
);
596 PluginInstanceParent
*
597 PluginModuleParent::InstCast(NPP instance
)
599 PluginInstanceParent
* ip
=
600 static_cast<PluginInstanceParent
*>(instance
->pdata
);
602 // If the plugin crashed and the PluginInstanceParent was deleted,
603 // instance->pdata will be NULL.
607 if (instance
!= ip
->mNPP
) {
608 NS_RUNTIMEABORT("Corrupted plugin data.");
614 PluginModuleParent::StreamCast(NPP instance
,
617 PluginInstanceParent
* ip
= InstCast(instance
);
621 BrowserStreamParent
* sp
=
622 static_cast<BrowserStreamParent
*>(static_cast<AStream
*>(s
->pdata
));
623 if (sp
->mNPP
!= ip
|| s
!= sp
->mStream
) {
624 NS_RUNTIMEABORT("Corrupted plugin stream data.");
630 PluginModuleParent::HasRequiredFunctions()
636 PluginModuleParent::AsyncSetWindow(NPP instance
, NPWindow
* window
)
638 PluginInstanceParent
* i
= InstCast(instance
);
640 return NS_ERROR_FAILURE
;
642 return i
->AsyncSetWindow(window
);
646 PluginModuleParent::GetSurface(NPP instance
, gfxASurface
** aSurface
)
648 PluginInstanceParent
* i
= InstCast(instance
);
650 return NS_ERROR_FAILURE
;
652 return i
->GetSurface(aSurface
);
655 #if defined(XP_UNIX) && !defined(XP_MACOSX)
657 PluginModuleParent::NP_Initialize(NPNetscapeFuncs
* bFuncs
, NPPluginFuncs
* pFuncs
, NPError
* error
)
659 PLUGIN_LOG_DEBUG_METHOD
;
664 *error
= NPERR_GENERIC_ERROR
;
665 return NS_ERROR_FAILURE
;
668 if (!CallNP_Initialize(&mPluginThread
, error
)) {
669 return NS_ERROR_FAILURE
;
671 else if (*error
!= NPERR_NO_ERROR
) {
675 SetPluginFuncs(pFuncs
);
680 PluginModuleParent::NP_Initialize(NPNetscapeFuncs
* bFuncs
, NPError
* error
)
682 PLUGIN_LOG_DEBUG_METHOD
;
687 *error
= NPERR_GENERIC_ERROR
;
688 return NS_ERROR_FAILURE
;
691 if (!CallNP_Initialize(&mPluginThread
, error
))
692 return NS_ERROR_FAILURE
;
699 PluginModuleParent::NP_Shutdown(NPError
* error
)
701 PLUGIN_LOG_DEBUG_METHOD
;
704 *error
= NPERR_GENERIC_ERROR
;
705 return NS_ERROR_FAILURE
;
708 bool ok
= CallNP_Shutdown(error
);
710 // if NP_Shutdown() is nested within another RPC call, this will
711 // break things. but lord help us if we're doing that anyway; the
712 // plugin dso will have been unloaded on the other side by the
713 // CallNP_Shutdown() message
716 return ok
? NS_OK
: NS_ERROR_FAILURE
;
720 PluginModuleParent::NP_GetMIMEDescription(const char** mimeDesc
)
722 PLUGIN_LOG_DEBUG_METHOD
;
724 *mimeDesc
= "application/x-foobar";
729 PluginModuleParent::NP_GetValue(void *future
, NPPVariable aVariable
,
730 void *aValue
, NPError
* error
)
732 PR_LOG(gPluginLog
, PR_LOG_WARNING
, ("%s Not implemented, requested variable %i", __FUNCTION__
,
735 //TODO: implement this correctly
736 *error
= NPERR_GENERIC_ERROR
;
740 #if defined(XP_WIN) || defined(XP_MACOSX) || defined(XP_OS2)
742 PluginModuleParent::NP_GetEntryPoints(NPPluginFuncs
* pFuncs
, NPError
* error
)
744 NS_ASSERTION(pFuncs
, "Null pointer!");
746 SetPluginFuncs(pFuncs
);
747 *error
= NPERR_NO_ERROR
;
753 PluginModuleParent::NPP_New(NPMIMEType pluginType
, NPP instance
,
754 uint16_t mode
, int16_t argc
, char* argn
[],
755 char* argv
[], NPSavedData
* saved
,
758 PLUGIN_LOG_DEBUG_METHOD
;
761 *error
= NPERR_GENERIC_ERROR
;
762 return NS_ERROR_FAILURE
;
765 // create the instance on the other side
766 InfallibleTArray
<nsCString
> names
;
767 InfallibleTArray
<nsCString
> values
;
769 for (int i
= 0; i
< argc
; ++i
) {
770 names
.AppendElement(NullableString(argn
[i
]));
771 values
.AppendElement(NullableString(argv
[i
]));
774 PluginInstanceParent
* parentInstance
=
775 new PluginInstanceParent(this, instance
,
776 nsDependentCString(pluginType
), mNPNIface
);
778 if (!parentInstance
->Init()) {
779 delete parentInstance
;
780 return NS_ERROR_FAILURE
;
783 instance
->pdata
= parentInstance
;
785 if (!CallPPluginInstanceConstructor(parentInstance
,
786 nsDependentCString(pluginType
), mode
,
787 names
, values
, error
)) {
788 // |parentInstance| is automatically deleted.
789 instance
->pdata
= nsnull
;
790 // if IPC is down, we'll get an immediate "failed" return, but
791 // without *error being set. So make sure that the error
792 // condition is signaled to nsNPAPIPluginInstance
793 if (NPERR_NO_ERROR
== *error
)
794 *error
= NPERR_GENERIC_ERROR
;
795 return NS_ERROR_FAILURE
;
798 if (*error
!= NPERR_NO_ERROR
) {
799 NPP_Destroy(instance
, 0);
800 return NS_ERROR_FAILURE
;
807 PluginModuleParent::AnswerNPN_GetValue_WithBoolReturn(const NPNVariable
& aVariable
,
811 NPBool boolVal
= false;
812 *aError
= mozilla::plugins::parent::_getvalue(nsnull
, aVariable
, &boolVal
);
813 *aBoolVal
= boolVal
? true : false;
817 #if defined(MOZ_WIDGET_QT)
818 static const int kMaxtimeToProcessEvents
= 30;
820 PluginModuleParent::AnswerProcessSomeEvents()
822 PLUGIN_LOG_DEBUG(("Spinning mini nested loop ..."));
823 QCoreApplication::processEvents(QEventLoop::AllEvents
, kMaxtimeToProcessEvents
);
825 PLUGIN_LOG_DEBUG(("... quitting mini nested loop"));
830 #elif defined(XP_MACOSX)
832 PluginModuleParent::AnswerProcessSomeEvents()
834 mozilla::plugins::PluginUtilsOSX::InvokeNativeEventLoop();
838 #elif !defined(MOZ_WIDGET_GTK2)
840 PluginModuleParent::AnswerProcessSomeEvents()
842 NS_RUNTIMEABORT("unreached");
847 static const int kMaxChancesToProcessEvents
= 20;
850 PluginModuleParent::AnswerProcessSomeEvents()
852 PLUGIN_LOG_DEBUG(("Spinning mini nested loop ..."));
855 for (; i
< kMaxChancesToProcessEvents
; ++i
)
856 if (!g_main_context_iteration(NULL
, FALSE
))
859 PLUGIN_LOG_DEBUG(("... quitting mini nested loop; processed %i tasks", i
));
866 PluginModuleParent::RecvProcessNativeEventsInRPCCall()
868 PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION
));
870 ProcessNativeEventsInRPCCall();
874 "PluginInstanceParent::RecvProcessNativeEventsInRPCCall not implemented!");
880 PluginModuleParent::RecvPluginShowWindow(const uint32_t& aWindowId
, const bool& aModal
,
881 const int32_t& aX
, const int32_t& aY
,
882 const size_t& aWidth
, const size_t& aHeight
)
884 PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION
));
885 #if defined(XP_MACOSX)
886 CGRect windowBound
= ::CGRectMake(aX
, aY
, aWidth
, aHeight
);
887 mac_plugin_interposing::parent::OnPluginShowWindow(aWindowId
, windowBound
, aModal
);
891 "PluginInstanceParent::RecvPluginShowWindow not implemented!");
897 PluginModuleParent::RecvPluginHideWindow(const uint32_t& aWindowId
)
899 PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION
));
900 #if defined(XP_MACOSX)
901 mac_plugin_interposing::parent::OnPluginHideWindow(aWindowId
, OtherSidePID());
905 "PluginInstanceParent::RecvPluginHideWindow not implemented!");
911 #define DEFAULT_REFRESH_MS 20 // CoreAnimation: 50 FPS
914 CAUpdate(nsITimer
*aTimer
, void *aClosure
) {
915 nsTObserverArray
<PluginInstanceParent
*> *ips
=
916 static_cast<nsTObserverArray
<PluginInstanceParent
*> *>(aClosure
);
917 nsTObserverArray
<PluginInstanceParent
*>::ForwardIterator
iter(*ips
);
918 while (iter
.HasMore()) {
919 iter
.GetNext()->Invalidate();
924 PluginModuleParent::AddToRefreshTimer(PluginInstanceParent
*aInstance
) {
925 if (mCATimerTargets
.Contains(aInstance
)) {
929 mCATimerTargets
.AppendElement(aInstance
);
930 if (mCATimerTargets
.Length() == 1) {
933 nsCOMPtr
<nsITimer
> xpcomTimer
= do_CreateInstance(NS_TIMER_CONTRACTID
, &rv
);
935 NS_WARNING("Could not create Core Animation timer for plugin.");
938 mCATimer
= xpcomTimer
;
940 mCATimer
->InitWithFuncCallback(CAUpdate
, &mCATimerTargets
, DEFAULT_REFRESH_MS
,
941 nsITimer::TYPE_REPEATING_SLACK
);
946 PluginModuleParent::RemoveFromRefreshTimer(PluginInstanceParent
*aInstance
) {
947 PRBool visibleRemoved
= mCATimerTargets
.RemoveElement(aInstance
);
948 if (visibleRemoved
&& mCATimerTargets
.IsEmpty()) {