LCOV - code coverage report
Current view: directory - dom/plugins/ipc - PluginModuleChild.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 774 0 0.0 %
Date: 2012-06-02 Functions: 103 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 : /* vim: set sw=4 ts=4 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                 :  *   Chris Jones <jones.chris.g@gmail.com>
      25                 :  *
      26                 :  * Alternatively, the contents of this file may be used under the terms of
      27                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      28                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      29                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      30                 :  * of those above. If you wish to allow use of your version of this file only
      31                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      32                 :  * use your version of this file under the terms of the MPL, indicate your
      33                 :  * decision by deleting the provisions above and replace them with the notice
      34                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      35                 :  * the provisions above, a recipient may use your version of this file under
      36                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      37                 :  *
      38                 :  * ***** END LICENSE BLOCK ***** */
      39                 : 
      40                 : #ifdef MOZ_WIDGET_QT
      41                 : #include <QtCore/QTimer>
      42                 : #include "nsQAppInstance.h"
      43                 : #include "NestedLoopTimer.h"
      44                 : #endif
      45                 : 
      46                 : #include "mozilla/plugins/PluginModuleChild.h"
      47                 : 
      48                 : /* This must occur *after* plugins/PluginModuleChild.h to avoid typedefs conflicts. */
      49                 : #include "mozilla/Util.h"
      50                 : 
      51                 : #include "mozilla/ipc/SyncChannel.h"
      52                 : 
      53                 : #ifdef MOZ_WIDGET_GTK2
      54                 : #include <gtk/gtk.h>
      55                 : #endif
      56                 : 
      57                 : #include "nsILocalFile.h"
      58                 : 
      59                 : #include "pratom.h"
      60                 : #include "nsDebug.h"
      61                 : #include "nsCOMPtr.h"
      62                 : #include "nsPluginsDir.h"
      63                 : #include "nsXULAppAPI.h"
      64                 : 
      65                 : #ifdef MOZ_X11
      66                 : # include "mozilla/X11Util.h"
      67                 : #endif
      68                 : #include "mozilla/plugins/PluginInstanceChild.h"
      69                 : #include "mozilla/plugins/StreamNotifyChild.h"
      70                 : #include "mozilla/plugins/BrowserStreamChild.h"
      71                 : #include "mozilla/plugins/PluginStreamChild.h"
      72                 : #include "PluginIdentifierChild.h"
      73                 : #include "mozilla/dom/CrashReporterChild.h"
      74                 : 
      75                 : #include "nsNPAPIPlugin.h"
      76                 : 
      77                 : #ifdef XP_WIN
      78                 : #include "COMMessageFilter.h"
      79                 : #include "nsWindowsDllInterceptor.h"
      80                 : #include "mozilla/widget/AudioSession.h"
      81                 : #endif
      82                 : 
      83                 : #ifdef MOZ_WIDGET_COCOA
      84                 : #include "PluginInterposeOSX.h"
      85                 : #include "PluginUtilsOSX.h"
      86                 : #endif
      87                 : 
      88                 : using namespace mozilla;
      89                 : using namespace mozilla::plugins;
      90                 : using mozilla::dom::CrashReporterChild;
      91                 : using mozilla::dom::PCrashReporterChild;
      92                 : 
      93                 : #if defined(XP_WIN)
      94                 : const PRUnichar * kFlashFullscreenClass = L"ShockwaveFlashFullScreen";
      95                 : const PRUnichar * kMozillaWindowClass = L"MozillaWindowClass";
      96                 : #endif
      97                 : 
      98                 : namespace {
      99                 : PluginModuleChild* gInstance = nsnull;
     100                 : }
     101                 : 
     102                 : #ifdef MOZ_WIDGET_QT
     103                 : typedef void (*_gtk_init_fn)(int argc, char **argv);
     104                 : static _gtk_init_fn s_gtk_init = nsnull;
     105                 : static PRLibrary *sGtkLib = nsnull;
     106                 : #endif
     107                 : 
     108                 : #ifdef XP_WIN
     109                 : // Used with fix for flash fullscreen window loosing focus.
     110                 : static bool gDelayFlashFocusReplyUntilEval = false;
     111                 : // Used to fix GetWindowInfo problems with internal flash settings dialogs
     112                 : static WindowsDllInterceptor sUser32Intercept;
     113                 : typedef BOOL (WINAPI *GetWindowInfoPtr)(HWND hwnd, PWINDOWINFO pwi);
     114                 : static GetWindowInfoPtr sGetWindowInfoPtrStub = NULL;
     115                 : static HWND sBrowserHwnd = NULL;
     116                 : #endif
     117                 : 
     118               0 : PluginModuleChild::PluginModuleChild()
     119                 :   : mLibrary(0)
     120                 :   , mPluginFilename("")
     121                 :   , mQuirks(QUIRKS_NOT_INITIALIZED)
     122                 :   , mShutdownFunc(0)
     123                 :   , mInitializeFunc(0)
     124                 : #if defined(OS_WIN) || defined(OS_MACOSX)
     125                 :   , mGetEntryPointsFunc(0)
     126                 : #elif defined(MOZ_WIDGET_GTK2)
     127               0 :   , mNestedLoopTimerId(0)
     128                 : #elif defined(MOZ_WIDGET_QT)
     129                 :   , mNestedLoopTimerObject(0)
     130                 : #endif
     131                 : #ifdef OS_WIN
     132                 :   , mNestedEventHook(NULL)
     133                 :   , mGlobalCallWndProcHook(NULL)
     134                 : #endif
     135                 : {
     136               0 :     NS_ASSERTION(!gInstance, "Something terribly wrong here!");
     137               0 :     memset(&mFunctions, 0, sizeof(mFunctions));
     138               0 :     memset(&mSavedData, 0, sizeof(mSavedData));
     139               0 :     gInstance = this;
     140               0 :     mUserAgent.SetIsVoid(true);
     141                 : #ifdef XP_MACOSX
     142                 :     mac_plugin_interposing::child::SetUpCocoaInterposing();
     143                 : #endif
     144               0 : }
     145                 : 
     146               0 : PluginModuleChild::~PluginModuleChild()
     147                 : {
     148               0 :     NS_ASSERTION(gInstance == this, "Something terribly wrong here!");
     149               0 :     if (mLibrary) {
     150               0 :         PR_UnloadLibrary(mLibrary);
     151                 :     }
     152                 : 
     153               0 :     DeinitGraphics();
     154                 : 
     155               0 :     gInstance = nsnull;
     156               0 : }
     157                 : 
     158                 : // static
     159                 : PluginModuleChild*
     160               0 : PluginModuleChild::current()
     161                 : {
     162               0 :     NS_ASSERTION(gInstance, "Null instance!");
     163               0 :     return gInstance;
     164                 : }
     165                 : 
     166                 : bool
     167               0 : PluginModuleChild::Init(const std::string& aPluginFilename,
     168                 :                         base::ProcessHandle aParentProcessHandle,
     169                 :                         MessageLoop* aIOLoop,
     170                 :                         IPC::Channel* aChannel)
     171                 : {
     172               0 :     PLUGIN_LOG_DEBUG_METHOD;
     173                 : 
     174                 : #ifdef XP_WIN
     175                 :     COMMessageFilter::Initialize(this);
     176                 : #endif
     177                 : 
     178               0 :     NS_ASSERTION(aChannel, "need a channel");
     179                 : 
     180               0 :     if (!mObjectMap.Init()) {
     181               0 :        NS_WARNING("Failed to initialize object hashtable!");
     182               0 :        return false;
     183                 :     }
     184                 : 
     185               0 :     if (!mStringIdentifiers.Init()) {
     186               0 :        NS_ERROR("Failed to initialize string identifier hashtable!");
     187               0 :        return false;
     188                 :     }
     189                 : 
     190               0 :     if (!mIntIdentifiers.Init()) {
     191               0 :        NS_ERROR("Failed to initialize int identifier hashtable!");
     192               0 :        return false;
     193                 :     }
     194                 : 
     195               0 :     if (!InitGraphics())
     196               0 :         return false;
     197                 : 
     198               0 :     mPluginFilename = aPluginFilename.c_str();
     199               0 :     nsCOMPtr<nsILocalFile> localFile;
     200               0 :     NS_NewLocalFile(NS_ConvertUTF8toUTF16(mPluginFilename),
     201                 :                     true,
     202               0 :                     getter_AddRefs(localFile));
     203                 : 
     204                 :     bool exists;
     205               0 :     localFile->Exists(&exists);
     206               0 :     NS_ASSERTION(exists, "plugin file ain't there");
     207                 : 
     208               0 :     nsPluginFile pluginFile(localFile);
     209                 : 
     210                 :     // Maemo flash can render with any provided rectangle and so does not
     211                 :     // require this quirk.
     212                 : #if defined(MOZ_X11) && !defined(MOZ_PLATFORM_MAEMO)
     213               0 :     nsPluginInfo info = nsPluginInfo();
     214               0 :     if (NS_FAILED(pluginFile.GetPluginInfo(info, &mLibrary)))
     215               0 :         return false;
     216                 : 
     217               0 :     NS_NAMED_LITERAL_CSTRING(flash10Head, "Shockwave Flash 10.");
     218               0 :     if (StringBeginsWith(nsDependentCString(info.fDescription), flash10Head)) {
     219               0 :         AddQuirk(QUIRK_FLASH_EXPOSE_COORD_TRANSLATION);
     220                 :     }
     221                 : 
     222               0 :     if (!mLibrary)
     223                 : #endif
     224                 :     {
     225               0 :         DebugOnly<nsresult> rv = pluginFile.LoadPlugin(&mLibrary);
     226               0 :         NS_ASSERTION(NS_OK == rv, "trouble with mPluginFile");
     227                 :     }
     228               0 :     NS_ASSERTION(mLibrary, "couldn't open shared object");
     229                 : 
     230               0 :     if (!Open(aChannel, aParentProcessHandle, aIOLoop))
     231               0 :         return false;
     232                 : 
     233               0 :     memset((void*) &mFunctions, 0, sizeof(mFunctions));
     234               0 :     mFunctions.size = sizeof(mFunctions);
     235               0 :     mFunctions.version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
     236                 : 
     237                 :     // TODO: use PluginPRLibrary here
     238                 : 
     239                 : #if defined(OS_LINUX)
     240                 :     mShutdownFunc =
     241               0 :         (NP_PLUGINSHUTDOWN) PR_FindFunctionSymbol(mLibrary, "NP_Shutdown");
     242                 : 
     243                 :     // create the new plugin handler
     244                 : 
     245                 :     mInitializeFunc =
     246               0 :         (NP_PLUGINUNIXINIT) PR_FindFunctionSymbol(mLibrary, "NP_Initialize");
     247               0 :     NS_ASSERTION(mInitializeFunc, "couldn't find NP_Initialize()");
     248                 : 
     249                 : #elif defined(OS_WIN) || defined(OS_MACOSX)
     250                 :     mShutdownFunc =
     251                 :         (NP_PLUGINSHUTDOWN)PR_FindFunctionSymbol(mLibrary, "NP_Shutdown");
     252                 : 
     253                 :     mGetEntryPointsFunc =
     254                 :         (NP_GETENTRYPOINTS)PR_FindSymbol(mLibrary, "NP_GetEntryPoints");
     255                 :     NS_ENSURE_TRUE(mGetEntryPointsFunc, false);
     256                 : 
     257                 :     mInitializeFunc =
     258                 :         (NP_PLUGININIT)PR_FindFunctionSymbol(mLibrary, "NP_Initialize");
     259                 :     NS_ENSURE_TRUE(mInitializeFunc, false);
     260                 : #else
     261                 : 
     262                 : #  error Please copy the initialization code from nsNPAPIPlugin.cpp
     263                 : 
     264                 : #endif
     265                 : 
     266                 : #ifdef XP_MACOSX
     267                 :     nsPluginInfo info = nsPluginInfo();
     268                 :     if (pluginFile.GetPluginInfo(info, &mLibrary) == NS_OK) {
     269                 :         mozilla::plugins::PluginUtilsOSX::SetProcessName(info.fName);
     270                 :     }
     271                 : #endif
     272                 : 
     273               0 :     return true;
     274                 : }
     275                 : 
     276                 : #if defined(MOZ_WIDGET_GTK2)
     277                 : typedef void (*GObjectDisposeFn)(GObject*);
     278                 : typedef gboolean (*GtkWidgetScrollEventFn)(GtkWidget*, GdkEventScroll*);
     279                 : typedef void (*GtkPlugEmbeddedFn)(GtkPlug*);
     280                 : 
     281                 : static GObjectDisposeFn real_gtk_plug_dispose;
     282                 : static GtkPlugEmbeddedFn real_gtk_plug_embedded;
     283                 : 
     284                 : static void
     285               0 : undo_bogus_unref(gpointer data, GObject* object, gboolean is_last_ref) {
     286               0 :     if (!is_last_ref) // recursion in g_object_ref
     287               0 :         return;
     288                 : 
     289               0 :     g_object_ref(object);
     290                 : }
     291                 : 
     292                 : static void
     293               0 : wrap_gtk_plug_dispose(GObject* object) {
     294                 :     // Work around Flash Player bug described in bug 538914.
     295                 :     //
     296                 :     // This function is called during gtk_widget_destroy and/or before
     297                 :     // the object's last reference is removed.  A reference to the
     298                 :     // object is held during the call so the ref count should not drop
     299                 :     // to zero.  However, Flash Player tries to destroy the GtkPlug
     300                 :     // using g_object_unref instead of gtk_widget_destroy.  The
     301                 :     // reference that Flash is removing actually belongs to the
     302                 :     // GtkPlug.  During real_gtk_plug_dispose, the GtkPlug removes its
     303                 :     // reference.
     304                 :     //
     305                 :     // A toggle ref is added to prevent premature deletion of the object
     306                 :     // caused by Flash Player's extra unref, and to detect when there are
     307                 :     // unexpectedly no other references.
     308               0 :     g_object_add_toggle_ref(object, undo_bogus_unref, NULL);
     309               0 :     (*real_gtk_plug_dispose)(object);
     310               0 :     g_object_remove_toggle_ref(object, undo_bogus_unref, NULL);
     311               0 : }
     312                 : 
     313                 : static gboolean
     314               0 : gtk_plug_scroll_event(GtkWidget *widget, GdkEventScroll *gdk_event)
     315                 : {
     316               0 :     if (!GTK_WIDGET_TOPLEVEL(widget)) // in same process as its GtkSocket
     317               0 :         return FALSE; // event not handled; propagate to GtkSocket
     318                 : 
     319               0 :     GdkWindow* socket_window = GTK_PLUG(widget)->socket_window;
     320               0 :     if (!socket_window)
     321               0 :         return FALSE;
     322                 : 
     323                 :     // Propagate the event to the embedder.
     324               0 :     GdkScreen* screen = gdk_drawable_get_screen(socket_window);
     325               0 :     GdkWindow* plug_window = widget->window;
     326               0 :     GdkWindow* event_window = gdk_event->window;
     327               0 :     gint x = gdk_event->x;
     328               0 :     gint y = gdk_event->y;
     329                 :     unsigned int button;
     330               0 :     unsigned int button_mask = 0;
     331                 :     XEvent xevent;
     332               0 :     Display* dpy = GDK_WINDOW_XDISPLAY(socket_window);
     333                 : 
     334                 :     /* Translate the event coordinates to the plug window,
     335                 :      * which should be aligned with the socket window.
     336                 :      */
     337               0 :     while (event_window != plug_window)
     338                 :     {
     339                 :         gint dx, dy;
     340                 : 
     341               0 :         gdk_window_get_position(event_window, &dx, &dy);
     342               0 :         x += dx;
     343               0 :         y += dy;
     344                 : 
     345               0 :         event_window = gdk_window_get_parent(event_window);
     346               0 :         if (!event_window)
     347               0 :             return FALSE;
     348                 :     }
     349                 : 
     350               0 :     switch (gdk_event->direction) {
     351                 :     case GDK_SCROLL_UP:
     352               0 :         button = 4;
     353               0 :         button_mask = Button4Mask;
     354               0 :         break;
     355                 :     case GDK_SCROLL_DOWN:
     356               0 :         button = 5;
     357               0 :         button_mask = Button5Mask;
     358               0 :         break;
     359                 :     case GDK_SCROLL_LEFT:
     360               0 :         button = 6;
     361               0 :         break;
     362                 :     case GDK_SCROLL_RIGHT:
     363               0 :         button = 7;
     364               0 :         break;
     365                 :     default:
     366               0 :         return FALSE; // unknown GdkScrollDirection
     367                 :     }
     368                 : 
     369               0 :     memset(&xevent, 0, sizeof(xevent));
     370               0 :     xevent.xbutton.type = ButtonPress;
     371               0 :     xevent.xbutton.window = GDK_WINDOW_XWINDOW(socket_window);
     372               0 :     xevent.xbutton.root = GDK_WINDOW_XWINDOW(gdk_screen_get_root_window(screen));
     373               0 :     xevent.xbutton.subwindow = GDK_WINDOW_XWINDOW(plug_window);
     374               0 :     xevent.xbutton.time = gdk_event->time;
     375               0 :     xevent.xbutton.x = x;
     376               0 :     xevent.xbutton.y = y;
     377               0 :     xevent.xbutton.x_root = gdk_event->x_root;
     378               0 :     xevent.xbutton.y_root = gdk_event->y_root;
     379               0 :     xevent.xbutton.state = gdk_event->state;
     380               0 :     xevent.xbutton.button = button;
     381               0 :     xevent.xbutton.same_screen = True;
     382                 : 
     383               0 :     gdk_error_trap_push();
     384                 : 
     385                 :     XSendEvent(dpy, xevent.xbutton.window,
     386               0 :                True, ButtonPressMask, &xevent);
     387                 : 
     388               0 :     xevent.xbutton.type = ButtonRelease;
     389               0 :     xevent.xbutton.state |= button_mask;
     390                 :     XSendEvent(dpy, xevent.xbutton.window,
     391               0 :                True, ButtonReleaseMask, &xevent);
     392                 : 
     393               0 :     gdk_display_sync(gdk_screen_get_display(screen));
     394               0 :     gdk_error_trap_pop();
     395                 : 
     396               0 :     return TRUE; // event handled
     397                 : }
     398                 : 
     399                 : static void
     400               0 : wrap_gtk_plug_embedded(GtkPlug* plug) {
     401               0 :     GdkWindow* socket_window = plug->socket_window;
     402               0 :     if (socket_window) {
     403               0 :         if (gtk_check_version(2,18,7) != NULL // older
     404               0 :             && g_object_get_data(G_OBJECT(socket_window),
     405               0 :                                  "moz-existed-before-set-window")) {
     406                 :             // Add missing reference for
     407                 :             // https://bugzilla.gnome.org/show_bug.cgi?id=607061
     408               0 :             g_object_ref(socket_window);
     409                 :         }
     410                 : 
     411                 :         // Ensure the window exists to make this GtkPlug behave like an
     412                 :         // in-process GtkPlug for Flash Player.  (Bugs 561308 and 539138).
     413               0 :         gtk_widget_realize(GTK_WIDGET(plug));
     414                 :     }
     415                 : 
     416               0 :     if (*real_gtk_plug_embedded) {
     417               0 :         (*real_gtk_plug_embedded)(plug);
     418                 :     }
     419               0 : }
     420                 : 
     421                 : //
     422                 : // The next four constants are knobs that can be tuned.  They trade
     423                 : // off potential UI lag from delayed event processing with CPU time.
     424                 : //
     425                 : static const gint kNestedLoopDetectorPriority = G_PRIORITY_HIGH_IDLE;
     426                 : // 90ms so that we can hopefully break livelocks before the user
     427                 : // notices UI lag (100ms)
     428                 : static const guint kNestedLoopDetectorIntervalMs = 90;
     429                 : 
     430                 : static const gint kBrowserEventPriority = G_PRIORITY_HIGH_IDLE;
     431                 : static const guint kBrowserEventIntervalMs = 10;
     432                 : 
     433                 : // static
     434                 : gboolean
     435               0 : PluginModuleChild::DetectNestedEventLoop(gpointer data)
     436                 : {
     437               0 :     PluginModuleChild* pmc = static_cast<PluginModuleChild*>(data);
     438                 : 
     439               0 :     NS_ABORT_IF_FALSE(0 != pmc->mNestedLoopTimerId,
     440                 :                       "callback after descheduling");
     441               0 :     NS_ABORT_IF_FALSE(pmc->mTopLoopDepth < g_main_depth(),
     442                 :                       "not canceled before returning to main event loop!");
     443                 : 
     444               0 :     PLUGIN_LOG_DEBUG(("Detected nested glib event loop"));
     445                 : 
     446                 :     // just detected a nested loop; start a timer that will
     447                 :     // periodically rpc-call back into the browser and process some
     448                 :     // events
     449                 :     pmc->mNestedLoopTimerId =
     450                 :         g_timeout_add_full(kBrowserEventPriority,
     451                 :                            kBrowserEventIntervalMs,
     452                 :                            PluginModuleChild::ProcessBrowserEvents,
     453                 :                            data,
     454               0 :                            NULL);
     455                 :     // cancel the nested-loop detection timer
     456               0 :     return FALSE;
     457                 : }
     458                 : 
     459                 : // static
     460                 : gboolean
     461               0 : PluginModuleChild::ProcessBrowserEvents(gpointer data)
     462                 : {
     463               0 :     PluginModuleChild* pmc = static_cast<PluginModuleChild*>(data);
     464                 : 
     465               0 :     NS_ABORT_IF_FALSE(pmc->mTopLoopDepth < g_main_depth(),
     466                 :                       "not canceled before returning to main event loop!");
     467                 : 
     468               0 :     pmc->CallProcessSomeEvents();
     469                 : 
     470               0 :     return TRUE;
     471                 : }
     472                 : 
     473                 : void
     474               0 : PluginModuleChild::EnteredCxxStack()
     475                 : {
     476               0 :     NS_ABORT_IF_FALSE(0 == mNestedLoopTimerId,
     477                 :                       "previous timer not descheduled");
     478                 : 
     479                 :     mNestedLoopTimerId =
     480                 :         g_timeout_add_full(kNestedLoopDetectorPriority,
     481                 :                            kNestedLoopDetectorIntervalMs,
     482                 :                            PluginModuleChild::DetectNestedEventLoop,
     483                 :                            this,
     484               0 :                            NULL);
     485                 : 
     486                 : #ifdef DEBUG
     487               0 :     mTopLoopDepth = g_main_depth();
     488                 : #endif
     489               0 : }
     490                 : 
     491                 : void
     492               0 : PluginModuleChild::ExitedCxxStack()
     493                 : {
     494               0 :     NS_ABORT_IF_FALSE(0 < mNestedLoopTimerId,
     495                 :                       "nested loop timeout not scheduled");
     496                 : 
     497               0 :     g_source_remove(mNestedLoopTimerId);
     498               0 :     mNestedLoopTimerId = 0;
     499               0 : }
     500                 : #elif defined (MOZ_WIDGET_QT)
     501                 : 
     502                 : void
     503                 : PluginModuleChild::EnteredCxxStack()
     504                 : {
     505                 :     NS_ABORT_IF_FALSE(mNestedLoopTimerObject == NULL,
     506                 :                       "previous timer not descheduled");
     507                 :     mNestedLoopTimerObject = new NestedLoopTimer(this);
     508                 :     QTimer::singleShot(kNestedLoopDetectorIntervalMs,
     509                 :                        mNestedLoopTimerObject, SLOT(timeOut()));
     510                 : }
     511                 : 
     512                 : void
     513                 : PluginModuleChild::ExitedCxxStack()
     514                 : {
     515                 :     NS_ABORT_IF_FALSE(mNestedLoopTimerObject != NULL,
     516                 :                       "nested loop timeout not scheduled");
     517                 :     delete mNestedLoopTimerObject;
     518                 :     mNestedLoopTimerObject = NULL;
     519                 : }
     520                 : 
     521                 : #endif
     522                 : 
     523                 : bool
     524               0 : PluginModuleChild::RecvSetParentHangTimeout(const uint32_t& aSeconds)
     525                 : {
     526                 : #ifdef XP_WIN
     527                 :     SetReplyTimeoutMs(((aSeconds > 0) ? (1000 * aSeconds) : 0));
     528                 : #endif
     529               0 :     return true;
     530                 : }
     531                 : 
     532                 : bool
     533               0 : PluginModuleChild::ShouldContinueFromReplyTimeout()
     534                 : {
     535                 : #ifdef XP_WIN
     536                 :     NS_RUNTIMEABORT("terminating child process");
     537                 : #endif
     538               0 :     return true;
     539                 : }
     540                 : 
     541                 : bool
     542               0 : PluginModuleChild::InitGraphics()
     543                 : {
     544                 : #if defined(MOZ_WIDGET_GTK2)
     545                 :     // Work around plugins that don't interact well with GDK
     546                 :     // client-side windows.
     547               0 :     PR_SetEnv("GDK_NATIVE_WINDOWS=1");
     548                 : 
     549               0 :     gtk_init(0, 0);
     550                 : 
     551                 :     // GtkPlug is a static class so will leak anyway but this ref makes sure.
     552               0 :     gpointer gtk_plug_class = g_type_class_ref(GTK_TYPE_PLUG);
     553                 : 
     554                 :     // The dispose method is a good place to hook into the destruction process
     555                 :     // because the reference count should be 1 the last time dispose is
     556                 :     // called.  (Toggle references wouldn't detect if the reference count
     557                 :     // might be higher.)
     558               0 :     GObjectDisposeFn* dispose = &G_OBJECT_CLASS(gtk_plug_class)->dispose;
     559               0 :     NS_ABORT_IF_FALSE(*dispose != wrap_gtk_plug_dispose,
     560                 :                       "InitGraphics called twice");
     561               0 :     real_gtk_plug_dispose = *dispose;
     562               0 :     *dispose = wrap_gtk_plug_dispose;
     563                 : 
     564                 :     // If we ever stop setting GDK_NATIVE_WINDOWS, we'll also need to
     565                 :     // gtk_widget_add_events GDK_SCROLL_MASK or GDK client-side windows will
     566                 :     // not tell us about the scroll events that it intercepts.  With native
     567                 :     // windows, this is called when GDK intercepts the events; if GDK doesn't
     568                 :     // intercept the events, then the X server will instead send them directly
     569                 :     // to an ancestor (embedder) window.
     570                 :     GtkWidgetScrollEventFn* scroll_event =
     571               0 :         &GTK_WIDGET_CLASS(gtk_plug_class)->scroll_event;
     572               0 :     if (!*scroll_event) {
     573               0 :         *scroll_event = gtk_plug_scroll_event;
     574                 :     }
     575                 : 
     576               0 :     GtkPlugEmbeddedFn* embedded = &GTK_PLUG_CLASS(gtk_plug_class)->embedded;
     577               0 :     real_gtk_plug_embedded = *embedded;
     578               0 :     *embedded = wrap_gtk_plug_embedded;
     579                 : 
     580                 : #elif defined(MOZ_WIDGET_QT)
     581                 :     nsQAppInstance::AddRef();
     582                 :     // Work around plugins that don't interact well without gtk initialized
     583                 :     // see bug 566845
     584                 : #if defined(MOZ_X11)
     585                 :     if (!sGtkLib)
     586                 :          sGtkLib = PR_LoadLibrary("libgtk-x11-2.0.so.0");
     587                 : #endif
     588                 :     if (sGtkLib) {
     589                 :          s_gtk_init = (_gtk_init_fn)PR_FindFunctionSymbol(sGtkLib, "gtk_init");
     590                 :          if (s_gtk_init)
     591                 :              s_gtk_init(0, 0);
     592                 :     }
     593                 : #else
     594                 :     // may not be necessary on all platforms
     595                 : #endif
     596                 : #ifdef MOZ_X11
     597                 :     // Do this after initializing GDK, or GDK will install its own handler.
     598               0 :     XRE_InstallX11ErrorHandler();
     599                 : #endif
     600               0 :     return true;
     601                 : }
     602                 : 
     603                 : void
     604               0 : PluginModuleChild::DeinitGraphics()
     605                 : {
     606                 : #ifdef MOZ_WIDGET_QT
     607                 :     nsQAppInstance::Release();
     608                 :     if (sGtkLib) {
     609                 :         PR_UnloadLibrary(sGtkLib);
     610                 :         sGtkLib = nsnull;
     611                 :         s_gtk_init = nsnull;
     612                 :     }
     613                 : #endif
     614                 : 
     615                 : #if defined(MOZ_X11) && defined(NS_FREE_PERMANENT_DATA)
     616                 :     // We free some data off of XDisplay close hooks, ensure they're
     617                 :     // run.  Closing the display is pretty scary, so we only do it to
     618                 :     // silence leak checkers.
     619               0 :     XCloseDisplay(DefaultXDisplay());
     620                 : #endif
     621               0 : }
     622                 : 
     623                 : bool
     624               0 : PluginModuleChild::AnswerNP_Shutdown(NPError *rv)
     625                 : {
     626               0 :     AssertPluginThread();
     627                 : 
     628                 : #if defined XP_WIN
     629                 :     mozilla::widget::StopAudioSession();
     630                 : #endif
     631                 : 
     632                 :     // the PluginModuleParent shuts down this process after this RPC
     633                 :     // call pops off its stack
     634                 : 
     635               0 :     *rv = mShutdownFunc ? mShutdownFunc() : NPERR_NO_ERROR;
     636                 : 
     637                 :     // weakly guard against re-entry after NP_Shutdown
     638               0 :     memset(&mFunctions, 0, sizeof(mFunctions));
     639                 : 
     640                 : #ifdef OS_WIN
     641                 :     ResetEventHooks();
     642                 : #endif
     643                 : 
     644               0 :     return true;
     645                 : }
     646                 : 
     647                 : bool
     648               0 : PluginModuleChild::AnswerOptionalFunctionsSupported(bool *aURLRedirectNotify,
     649                 :                                                     bool *aClearSiteData,
     650                 :                                                     bool *aGetSitesWithData)
     651                 : {
     652               0 :     *aURLRedirectNotify = !!mFunctions.urlredirectnotify;
     653               0 :     *aClearSiteData = !!mFunctions.clearsitedata;
     654               0 :     *aGetSitesWithData = !!mFunctions.getsiteswithdata;
     655               0 :     return true;
     656                 : }
     657                 : 
     658                 : bool
     659               0 : PluginModuleChild::AnswerNPP_ClearSiteData(const nsCString& aSite,
     660                 :                                            const uint64_t& aFlags,
     661                 :                                            const uint64_t& aMaxAge,
     662                 :                                            NPError* aResult)
     663                 : {
     664                 :     *aResult =
     665               0 :         mFunctions.clearsitedata(NullableStringGet(aSite), aFlags, aMaxAge);
     666               0 :     return true;
     667                 : }
     668                 : 
     669                 : bool
     670               0 : PluginModuleChild::AnswerNPP_GetSitesWithData(InfallibleTArray<nsCString>* aResult)
     671                 : {
     672               0 :     char** result = mFunctions.getsiteswithdata();
     673               0 :     if (!result)
     674               0 :         return true;
     675                 : 
     676               0 :     char** iterator = result;
     677               0 :     while (*iterator) {
     678               0 :         aResult->AppendElement(*iterator);
     679               0 :         NS_Free(*iterator);
     680               0 :         ++iterator;
     681                 :     }
     682               0 :     NS_Free(result);
     683                 : 
     684               0 :     return true;
     685                 : }
     686                 : 
     687                 : bool
     688               0 : PluginModuleChild::RecvSetAudioSessionData(const nsID& aId,
     689                 :                                            const nsString& aDisplayName,
     690                 :                                            const nsString& aIconPath)
     691                 : {
     692                 : #if !defined XP_WIN
     693               0 :     NS_RUNTIMEABORT("Not Reached!");
     694               0 :     return false;
     695                 : #else
     696                 :     nsresult rv = mozilla::widget::RecvAudioSessionData(aId, aDisplayName, aIconPath);
     697                 :     NS_ENSURE_SUCCESS(rv, true); // Bail early if this fails
     698                 : 
     699                 :     // Ignore failures here; we can't really do anything about them
     700                 :     mozilla::widget::StartAudioSession();
     701                 :     return true;
     702                 : #endif
     703                 : }
     704                 : 
     705                 : void
     706               0 : PluginModuleChild::QuickExit()
     707                 : {
     708               0 :     NS_WARNING("plugin process _exit()ing");
     709               0 :     _exit(0);
     710                 : }
     711                 : 
     712                 : PCrashReporterChild*
     713               0 : PluginModuleChild::AllocPCrashReporter(mozilla::dom::NativeThreadId* id,
     714                 :                                        PRUint32* processType)
     715                 : {
     716               0 :     return new CrashReporterChild();
     717                 : }
     718                 : 
     719                 : bool
     720               0 : PluginModuleChild::DeallocPCrashReporter(PCrashReporterChild* actor)
     721                 : {
     722               0 :     delete actor;
     723               0 :     return true;
     724                 : }
     725                 : 
     726                 : bool
     727               0 : PluginModuleChild::AnswerPCrashReporterConstructor(
     728                 :         PCrashReporterChild* actor,
     729                 :         mozilla::dom::NativeThreadId* id,
     730                 :         PRUint32* processType)
     731                 : {
     732                 : #ifdef MOZ_CRASHREPORTER
     733               0 :     *id = CrashReporter::CurrentThreadId();
     734               0 :     *processType = XRE_GetProcessType();
     735                 : #endif
     736               0 :     return true;
     737                 : }
     738                 : 
     739                 : void
     740               0 : PluginModuleChild::ActorDestroy(ActorDestroyReason why)
     741                 : {
     742               0 :     if (AbnormalShutdown == why) {
     743               0 :         NS_WARNING("shutting down early because of crash!");
     744               0 :         QuickExit();
     745                 :     }
     746                 : 
     747                 :     // doesn't matter why we're being destroyed; it's up to us to
     748                 :     // initiate (clean) shutdown
     749               0 :     XRE_ShutdownChildProcess();
     750               0 : }
     751                 : 
     752                 : void
     753               0 : PluginModuleChild::CleanUp()
     754                 : {
     755               0 : }
     756                 : 
     757                 : const char*
     758               0 : PluginModuleChild::GetUserAgent()
     759                 : {
     760               0 :     if (mUserAgent.IsVoid() && !CallNPN_UserAgent(&mUserAgent))
     761               0 :         return NULL;
     762                 : 
     763               0 :     return NullableStringGet(mUserAgent);
     764                 : }
     765                 : 
     766                 : bool
     767               0 : PluginModuleChild::RegisterActorForNPObject(NPObject* aObject,
     768                 :                                             PluginScriptableObjectChild* aActor)
     769                 : {
     770               0 :     AssertPluginThread();
     771               0 :     NS_ASSERTION(mObjectMap.IsInitialized(), "Not initialized!");
     772               0 :     NS_ASSERTION(aObject && aActor, "Null pointer!");
     773                 : 
     774               0 :     NPObjectData* d = mObjectMap.GetEntry(aObject);
     775               0 :     if (!d) {
     776               0 :         NS_ERROR("NPObject not in object table");
     777               0 :         return false;
     778                 :     }
     779                 : 
     780               0 :     d->actor = aActor;
     781               0 :     return true;
     782                 : }
     783                 : 
     784                 : void
     785               0 : PluginModuleChild::UnregisterActorForNPObject(NPObject* aObject)
     786                 : {
     787               0 :     AssertPluginThread();
     788               0 :     NS_ASSERTION(mObjectMap.IsInitialized(), "Not initialized!");
     789               0 :     NS_ASSERTION(aObject, "Null pointer!");
     790                 : 
     791               0 :     mObjectMap.GetEntry(aObject)->actor = NULL;
     792               0 : }
     793                 : 
     794                 : PluginScriptableObjectChild*
     795               0 : PluginModuleChild::GetActorForNPObject(NPObject* aObject)
     796                 : {
     797               0 :     AssertPluginThread();
     798               0 :     NS_ASSERTION(mObjectMap.IsInitialized(), "Not initialized!");
     799               0 :     NS_ASSERTION(aObject, "Null pointer!");
     800                 : 
     801               0 :     NPObjectData* d = mObjectMap.GetEntry(aObject);
     802               0 :     if (!d) {
     803               0 :         NS_ERROR("Plugin using object not created with NPN_CreateObject?");
     804               0 :         return NULL;
     805                 :     }
     806                 : 
     807               0 :     return d->actor;
     808                 : }
     809                 : 
     810                 : #ifdef DEBUG
     811                 : bool
     812               0 : PluginModuleChild::NPObjectIsRegistered(NPObject* aObject)
     813                 : {
     814               0 :     return !!mObjectMap.GetEntry(aObject);
     815                 : }
     816                 : #endif
     817                 : 
     818                 : //-----------------------------------------------------------------------------
     819                 : // FIXME/cjones: just getting this out of the way for the moment ...
     820                 : 
     821                 : namespace mozilla {
     822                 : namespace plugins {
     823                 : namespace child {
     824                 : 
     825                 : static NPError NP_CALLBACK
     826                 : _requestread(NPStream *pstream, NPByteRange *rangeList);
     827                 : 
     828                 : static NPError NP_CALLBACK
     829                 : _geturlnotify(NPP aNPP, const char* relativeURL, const char* target,
     830                 :               void* notifyData);
     831                 : 
     832                 : static NPError NP_CALLBACK
     833                 : _getvalue(NPP aNPP, NPNVariable variable, void *r_value);
     834                 : 
     835                 : static NPError NP_CALLBACK
     836                 : _setvalue(NPP aNPP, NPPVariable variable, void *r_value);
     837                 : 
     838                 : static NPError NP_CALLBACK
     839                 : _geturl(NPP aNPP, const char* relativeURL, const char* target);
     840                 : 
     841                 : static NPError NP_CALLBACK
     842                 : _posturlnotify(NPP aNPP, const char* relativeURL, const char *target,
     843                 :                uint32_t len, const char *buf, NPBool file, void* notifyData);
     844                 : 
     845                 : static NPError NP_CALLBACK
     846                 : _posturl(NPP aNPP, const char* relativeURL, const char *target, uint32_t len,
     847                 :          const char *buf, NPBool file);
     848                 : 
     849                 : static NPError NP_CALLBACK
     850                 : _newstream(NPP aNPP, NPMIMEType type, const char* window, NPStream** pstream);
     851                 : 
     852                 : static int32_t NP_CALLBACK
     853                 : _write(NPP aNPP, NPStream *pstream, int32_t len, void *buffer);
     854                 : 
     855                 : static NPError NP_CALLBACK
     856                 : _destroystream(NPP aNPP, NPStream *pstream, NPError reason);
     857                 : 
     858                 : static void NP_CALLBACK
     859                 : _status(NPP aNPP, const char *message);
     860                 : 
     861                 : static void NP_CALLBACK
     862                 : _memfree (void *ptr);
     863                 : 
     864                 : static uint32_t NP_CALLBACK
     865                 : _memflush(uint32_t size);
     866                 : 
     867                 : static void NP_CALLBACK
     868                 : _reloadplugins(NPBool reloadPages);
     869                 : 
     870                 : static void NP_CALLBACK
     871                 : _invalidaterect(NPP aNPP, NPRect *invalidRect);
     872                 : 
     873                 : static void NP_CALLBACK
     874                 : _invalidateregion(NPP aNPP, NPRegion invalidRegion);
     875                 : 
     876                 : static void NP_CALLBACK
     877                 : _forceredraw(NPP aNPP);
     878                 : 
     879                 : static const char* NP_CALLBACK
     880                 : _useragent(NPP aNPP);
     881                 : 
     882                 : static void* NP_CALLBACK
     883                 : _memalloc (uint32_t size);
     884                 : 
     885                 : // Deprecated entry points for the old Java plugin.
     886                 : static void* NP_CALLBACK /* OJI type: JRIEnv* */
     887                 : _getjavaenv(void);
     888                 : 
     889                 : // Deprecated entry points for the old Java plugin.
     890                 : static void* NP_CALLBACK /* OJI type: jref */
     891                 : _getjavapeer(NPP aNPP);
     892                 : 
     893                 : static bool NP_CALLBACK
     894                 : _invoke(NPP aNPP, NPObject* npobj, NPIdentifier method, const NPVariant *args,
     895                 :         uint32_t argCount, NPVariant *result);
     896                 : 
     897                 : static bool NP_CALLBACK
     898                 : _invokedefault(NPP aNPP, NPObject* npobj, const NPVariant *args,
     899                 :                uint32_t argCount, NPVariant *result);
     900                 : 
     901                 : static bool NP_CALLBACK
     902                 : _evaluate(NPP aNPP, NPObject* npobj, NPString *script, NPVariant *result);
     903                 : 
     904                 : static bool NP_CALLBACK
     905                 : _getproperty(NPP aNPP, NPObject* npobj, NPIdentifier property,
     906                 :              NPVariant *result);
     907                 : 
     908                 : static bool NP_CALLBACK
     909                 : _setproperty(NPP aNPP, NPObject* npobj, NPIdentifier property,
     910                 :              const NPVariant *value);
     911                 : 
     912                 : static bool NP_CALLBACK
     913                 : _removeproperty(NPP aNPP, NPObject* npobj, NPIdentifier property);
     914                 : 
     915                 : static bool NP_CALLBACK
     916                 : _hasproperty(NPP aNPP, NPObject* npobj, NPIdentifier propertyName);
     917                 : 
     918                 : static bool NP_CALLBACK
     919                 : _hasmethod(NPP aNPP, NPObject* npobj, NPIdentifier methodName);
     920                 : 
     921                 : static bool NP_CALLBACK
     922                 : _enumerate(NPP aNPP, NPObject *npobj, NPIdentifier **identifier,
     923                 :            uint32_t *count);
     924                 : 
     925                 : static bool NP_CALLBACK
     926                 : _construct(NPP aNPP, NPObject* npobj, const NPVariant *args,
     927                 :            uint32_t argCount, NPVariant *result);
     928                 : 
     929                 : static void NP_CALLBACK
     930                 : _releasevariantvalue(NPVariant *variant);
     931                 : 
     932                 : static void NP_CALLBACK
     933                 : _setexception(NPObject* npobj, const NPUTF8 *message);
     934                 : 
     935                 : static void NP_CALLBACK
     936                 : _pushpopupsenabledstate(NPP aNPP, NPBool enabled);
     937                 : 
     938                 : static void NP_CALLBACK
     939                 : _poppopupsenabledstate(NPP aNPP);
     940                 : 
     941                 : static void NP_CALLBACK
     942                 : _pluginthreadasynccall(NPP instance, PluginThreadCallback func,
     943                 :                        void *userData);
     944                 : 
     945                 : static NPError NP_CALLBACK
     946                 : _getvalueforurl(NPP npp, NPNURLVariable variable, const char *url,
     947                 :                 char **value, uint32_t *len);
     948                 : 
     949                 : static NPError NP_CALLBACK
     950                 : _setvalueforurl(NPP npp, NPNURLVariable variable, const char *url,
     951                 :                 const char *value, uint32_t len);
     952                 : 
     953                 : static NPError NP_CALLBACK
     954                 : _getauthenticationinfo(NPP npp, const char *protocol,
     955                 :                        const char *host, int32_t port,
     956                 :                        const char *scheme, const char *realm,
     957                 :                        char **username, uint32_t *ulen,
     958                 :                        char **password, uint32_t *plen);
     959                 : 
     960                 : static uint32_t NP_CALLBACK
     961                 : _scheduletimer(NPP instance, uint32_t interval, NPBool repeat,
     962                 :                void (*timerFunc)(NPP npp, uint32_t timerID));
     963                 : 
     964                 : static void NP_CALLBACK
     965                 : _unscheduletimer(NPP instance, uint32_t timerID);
     966                 : 
     967                 : static NPError NP_CALLBACK
     968                 : _popupcontextmenu(NPP instance, NPMenu* menu);
     969                 : 
     970                 : static NPBool NP_CALLBACK
     971                 : _convertpoint(NPP instance, 
     972                 :               double sourceX, double sourceY, NPCoordinateSpace sourceSpace,
     973                 :               double *destX, double *destY, NPCoordinateSpace destSpace);
     974                 : 
     975                 : static void NP_CALLBACK
     976                 : _urlredirectresponse(NPP instance, void* notifyData, NPBool allow);
     977                 : 
     978                 : static NPError NP_CALLBACK
     979                 : _initasyncsurface(NPP instance, NPSize *size,
     980                 :                   NPImageFormat format, void *initData,
     981                 :                   NPAsyncSurface *surface);
     982                 : 
     983                 : static NPError NP_CALLBACK
     984                 : _finalizeasyncsurface(NPP instance, NPAsyncSurface *surface);
     985                 : 
     986                 : static void NP_CALLBACK
     987                 : _setcurrentasyncsurface(NPP instance, NPAsyncSurface *surface, NPRect *changed);
     988                 : 
     989                 : } /* namespace child */
     990                 : } /* namespace plugins */
     991                 : } /* namespace mozilla */
     992                 : 
     993                 : const NPNetscapeFuncs PluginModuleChild::sBrowserFuncs = {
     994                 :     sizeof(sBrowserFuncs),
     995                 :     (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR,
     996                 :     mozilla::plugins::child::_geturl,
     997                 :     mozilla::plugins::child::_posturl,
     998                 :     mozilla::plugins::child::_requestread,
     999                 :     mozilla::plugins::child::_newstream,
    1000                 :     mozilla::plugins::child::_write,
    1001                 :     mozilla::plugins::child::_destroystream,
    1002                 :     mozilla::plugins::child::_status,
    1003                 :     mozilla::plugins::child::_useragent,
    1004                 :     mozilla::plugins::child::_memalloc,
    1005                 :     mozilla::plugins::child::_memfree,
    1006                 :     mozilla::plugins::child::_memflush,
    1007                 :     mozilla::plugins::child::_reloadplugins,
    1008                 :     mozilla::plugins::child::_getjavaenv,
    1009                 :     mozilla::plugins::child::_getjavapeer,
    1010                 :     mozilla::plugins::child::_geturlnotify,
    1011                 :     mozilla::plugins::child::_posturlnotify,
    1012                 :     mozilla::plugins::child::_getvalue,
    1013                 :     mozilla::plugins::child::_setvalue,
    1014                 :     mozilla::plugins::child::_invalidaterect,
    1015                 :     mozilla::plugins::child::_invalidateregion,
    1016                 :     mozilla::plugins::child::_forceredraw,
    1017                 :     PluginModuleChild::NPN_GetStringIdentifier,
    1018                 :     PluginModuleChild::NPN_GetStringIdentifiers,
    1019                 :     PluginModuleChild::NPN_GetIntIdentifier,
    1020                 :     PluginModuleChild::NPN_IdentifierIsString,
    1021                 :     PluginModuleChild::NPN_UTF8FromIdentifier,
    1022                 :     PluginModuleChild::NPN_IntFromIdentifier,
    1023                 :     PluginModuleChild::NPN_CreateObject,
    1024                 :     PluginModuleChild::NPN_RetainObject,
    1025                 :     PluginModuleChild::NPN_ReleaseObject,
    1026                 :     mozilla::plugins::child::_invoke,
    1027                 :     mozilla::plugins::child::_invokedefault,
    1028                 :     mozilla::plugins::child::_evaluate,
    1029                 :     mozilla::plugins::child::_getproperty,
    1030                 :     mozilla::plugins::child::_setproperty,
    1031                 :     mozilla::plugins::child::_removeproperty,
    1032                 :     mozilla::plugins::child::_hasproperty,
    1033                 :     mozilla::plugins::child::_hasmethod,
    1034                 :     mozilla::plugins::child::_releasevariantvalue,
    1035                 :     mozilla::plugins::child::_setexception,
    1036                 :     mozilla::plugins::child::_pushpopupsenabledstate,
    1037                 :     mozilla::plugins::child::_poppopupsenabledstate,
    1038                 :     mozilla::plugins::child::_enumerate,
    1039                 :     mozilla::plugins::child::_pluginthreadasynccall,
    1040                 :     mozilla::plugins::child::_construct,
    1041                 :     mozilla::plugins::child::_getvalueforurl,
    1042                 :     mozilla::plugins::child::_setvalueforurl,
    1043                 :     mozilla::plugins::child::_getauthenticationinfo,
    1044                 :     mozilla::plugins::child::_scheduletimer,
    1045                 :     mozilla::plugins::child::_unscheduletimer,
    1046                 :     mozilla::plugins::child::_popupcontextmenu,
    1047                 :     mozilla::plugins::child::_convertpoint,
    1048                 :     NULL, // handleevent, unimplemented
    1049                 :     NULL, // unfocusinstance, unimplemented
    1050                 :     mozilla::plugins::child::_urlredirectresponse,
    1051                 :     mozilla::plugins::child::_initasyncsurface,
    1052                 :     mozilla::plugins::child::_finalizeasyncsurface,
    1053                 :     mozilla::plugins::child::_setcurrentasyncsurface
    1054                 : };
    1055                 : 
    1056                 : PluginInstanceChild*
    1057               0 : InstCast(NPP aNPP)
    1058                 : {
    1059               0 :     NS_ABORT_IF_FALSE(!!(aNPP->ndata), "nil instance");
    1060               0 :     return static_cast<PluginInstanceChild*>(aNPP->ndata);
    1061                 : }
    1062                 : 
    1063                 : namespace mozilla {
    1064                 : namespace plugins {
    1065                 : namespace child {
    1066                 : 
    1067                 : NPError NP_CALLBACK
    1068               0 : _requestread(NPStream* aStream,
    1069                 :              NPByteRange* aRangeList)
    1070                 : {
    1071               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1072               0 :     ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM);
    1073                 : 
    1074                 :     BrowserStreamChild* bs =
    1075               0 :         static_cast<BrowserStreamChild*>(static_cast<AStream*>(aStream->ndata));
    1076               0 :     bs->EnsureCorrectStream(aStream);
    1077               0 :     return bs->NPN_RequestRead(aRangeList);
    1078                 : }
    1079                 : 
    1080                 : NPError NP_CALLBACK
    1081               0 : _geturlnotify(NPP aNPP,
    1082                 :               const char* aRelativeURL,
    1083                 :               const char* aTarget,
    1084                 :               void* aNotifyData)
    1085                 : {
    1086               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1087               0 :     ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM);
    1088                 : 
    1089               0 :     if (!aNPP) // NULL check for nspluginwrapper (bug 561690)
    1090               0 :         return NPERR_INVALID_INSTANCE_ERROR;
    1091                 : 
    1092               0 :     nsCString url = NullableString(aRelativeURL);
    1093               0 :     StreamNotifyChild* sn = new StreamNotifyChild(url);
    1094                 : 
    1095                 :     NPError err;
    1096               0 :     InstCast(aNPP)->CallPStreamNotifyConstructor(
    1097               0 :         sn, url, NullableString(aTarget), false, nsCString(), false, &err);
    1098                 : 
    1099               0 :     if (NPERR_NO_ERROR == err) {
    1100                 :         // If NPN_PostURLNotify fails, the parent will immediately send us
    1101                 :         // a PStreamNotifyDestructor, which should not call NPP_URLNotify.
    1102               0 :         sn->SetValid(aNotifyData);
    1103                 :     }
    1104                 : 
    1105               0 :     return err;
    1106                 : }
    1107                 : 
    1108                 : NPError NP_CALLBACK
    1109               0 : _getvalue(NPP aNPP,
    1110                 :           NPNVariable aVariable,
    1111                 :           void* aValue)
    1112                 : {
    1113               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1114               0 :     ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM);
    1115                 : 
    1116               0 :     switch (aVariable) {
    1117                 :         // Copied from nsNPAPIPlugin.cpp
    1118                 :         case NPNVToolkit:
    1119                 : #if defined(MOZ_WIDGET_GTK2) || defined(MOZ_WIDGET_QT)
    1120               0 :             *static_cast<NPNToolkitType*>(aValue) = NPNVGtk2;
    1121               0 :             return NPERR_NO_ERROR;
    1122                 : #endif
    1123                 :             return NPERR_GENERIC_ERROR;
    1124                 : 
    1125                 :         case NPNVjavascriptEnabledBool: // Intentional fall-through
    1126                 :         case NPNVasdEnabledBool: // Intentional fall-through
    1127                 :         case NPNVisOfflineBool: // Intentional fall-through
    1128                 :         case NPNVSupportsXEmbedBool: // Intentional fall-through
    1129                 :         case NPNVSupportsWindowless: // Intentional fall-through
    1130                 :         case NPNVprivateModeBool: {
    1131                 :             NPError result;
    1132                 :             bool value;
    1133               0 :             PluginModuleChild::current()->
    1134               0 :                 CallNPN_GetValue_WithBoolReturn(aVariable, &result, &value);
    1135               0 :             *(NPBool*)aValue = value ? true : false;
    1136               0 :             return result;
    1137                 :         }
    1138                 : 
    1139                 :         default: {
    1140               0 :             if (aNPP) {
    1141               0 :                 return InstCast(aNPP)->NPN_GetValue(aVariable, aValue);
    1142                 :             }
    1143                 : 
    1144               0 :             NS_WARNING("Null NPP!");
    1145               0 :             return NPERR_INVALID_INSTANCE_ERROR;
    1146                 :         }
    1147                 :     }
    1148                 : 
    1149                 :     NS_NOTREACHED("Shouldn't get here!");
    1150                 :     return NPERR_GENERIC_ERROR;
    1151                 : }
    1152                 : 
    1153                 : NPError NP_CALLBACK
    1154               0 : _setvalue(NPP aNPP,
    1155                 :           NPPVariable aVariable,
    1156                 :           void* aValue)
    1157                 : {
    1158               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1159               0 :     ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM);
    1160               0 :     return InstCast(aNPP)->NPN_SetValue(aVariable, aValue);
    1161                 : }
    1162                 : 
    1163                 : NPError NP_CALLBACK
    1164               0 : _geturl(NPP aNPP,
    1165                 :         const char* aRelativeURL,
    1166                 :         const char* aTarget)
    1167                 : {
    1168               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1169               0 :     ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM);
    1170                 : 
    1171                 :     NPError err;
    1172               0 :     InstCast(aNPP)->CallNPN_GetURL(NullableString(aRelativeURL),
    1173               0 :                                    NullableString(aTarget), &err);
    1174               0 :     return err;
    1175                 : }
    1176                 : 
    1177                 : NPError NP_CALLBACK
    1178               0 : _posturlnotify(NPP aNPP,
    1179                 :                const char* aRelativeURL,
    1180                 :                const char* aTarget,
    1181                 :                uint32_t aLength,
    1182                 :                const char* aBuffer,
    1183                 :                NPBool aIsFile,
    1184                 :                void* aNotifyData)
    1185                 : {
    1186               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1187               0 :     ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM);
    1188                 : 
    1189               0 :     if (!aBuffer)
    1190               0 :         return NPERR_INVALID_PARAM;
    1191                 : 
    1192               0 :     nsCString url = NullableString(aRelativeURL);
    1193               0 :     StreamNotifyChild* sn = new StreamNotifyChild(url);
    1194                 : 
    1195                 :     NPError err;
    1196               0 :     InstCast(aNPP)->CallPStreamNotifyConstructor(
    1197               0 :         sn, url, NullableString(aTarget), true,
    1198               0 :         nsCString(aBuffer, aLength), aIsFile, &err);
    1199                 : 
    1200               0 :     if (NPERR_NO_ERROR == err) {
    1201                 :         // If NPN_PostURLNotify fails, the parent will immediately send us
    1202                 :         // a PStreamNotifyDestructor, which should not call NPP_URLNotify.
    1203               0 :         sn->SetValid(aNotifyData);
    1204                 :     }
    1205                 : 
    1206               0 :     return err;
    1207                 : }
    1208                 : 
    1209                 : NPError NP_CALLBACK
    1210               0 : _posturl(NPP aNPP,
    1211                 :          const char* aRelativeURL,
    1212                 :          const char* aTarget,
    1213                 :          uint32_t aLength,
    1214                 :          const char* aBuffer,
    1215                 :          NPBool aIsFile)
    1216                 : {
    1217               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1218               0 :     ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM);
    1219                 : 
    1220                 :     NPError err;
    1221                 :     // FIXME what should happen when |aBuffer| is null?
    1222               0 :     InstCast(aNPP)->CallNPN_PostURL(NullableString(aRelativeURL),
    1223               0 :                                     NullableString(aTarget),
    1224               0 :                                     nsDependentCString(aBuffer, aLength),
    1225               0 :                                     aIsFile, &err);
    1226               0 :     return err;
    1227                 : }
    1228                 : 
    1229                 : NPError NP_CALLBACK
    1230               0 : _newstream(NPP aNPP,
    1231                 :            NPMIMEType aMIMEType,
    1232                 :            const char* aWindow,
    1233                 :            NPStream** aStream)
    1234                 : {
    1235               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1236               0 :     ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM);
    1237               0 :     return InstCast(aNPP)->NPN_NewStream(aMIMEType, aWindow, aStream);
    1238                 : }
    1239                 : 
    1240                 : int32_t NP_CALLBACK
    1241               0 : _write(NPP aNPP,
    1242                 :        NPStream* aStream,
    1243                 :        int32_t aLength,
    1244                 :        void* aBuffer)
    1245                 : {
    1246               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1247               0 :     ENSURE_PLUGIN_THREAD(0);
    1248                 : 
    1249                 :     PluginStreamChild* ps =
    1250               0 :         static_cast<PluginStreamChild*>(static_cast<AStream*>(aStream->ndata));
    1251               0 :     ps->EnsureCorrectInstance(InstCast(aNPP));
    1252               0 :     ps->EnsureCorrectStream(aStream);
    1253               0 :     return ps->NPN_Write(aLength, aBuffer);
    1254                 : }
    1255                 : 
    1256                 : NPError NP_CALLBACK
    1257               0 : _destroystream(NPP aNPP,
    1258                 :                NPStream* aStream,
    1259                 :                NPError aReason)
    1260                 : {
    1261               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1262               0 :     ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM);
    1263                 : 
    1264               0 :     PluginInstanceChild* p = InstCast(aNPP);
    1265               0 :     AStream* s = static_cast<AStream*>(aStream->ndata);
    1266               0 :     if (s->IsBrowserStream()) {
    1267               0 :         BrowserStreamChild* bs = static_cast<BrowserStreamChild*>(s);
    1268               0 :         bs->EnsureCorrectInstance(p);
    1269               0 :         bs->NPN_DestroyStream(aReason);
    1270                 :     }
    1271                 :     else {
    1272               0 :         PluginStreamChild* ps = static_cast<PluginStreamChild*>(s);
    1273               0 :         ps->EnsureCorrectInstance(p);
    1274               0 :         PPluginStreamChild::Call__delete__(ps, aReason, false);
    1275                 :     }
    1276               0 :     return NPERR_NO_ERROR;
    1277                 : }
    1278                 : 
    1279                 : void NP_CALLBACK
    1280               0 : _status(NPP aNPP,
    1281                 :         const char* aMessage)
    1282                 : {
    1283               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1284               0 :     ENSURE_PLUGIN_THREAD_VOID();
    1285               0 :     NS_WARNING("Not yet implemented!");
    1286                 : }
    1287                 : 
    1288                 : void NP_CALLBACK
    1289               0 : _memfree(void* aPtr)
    1290                 : {
    1291               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1292                 :     // Only assert plugin thread here for consistency with in-process plugins.
    1293               0 :     AssertPluginThread();
    1294               0 :     NS_Free(aPtr);
    1295               0 : }
    1296                 : 
    1297                 : uint32_t NP_CALLBACK
    1298               0 : _memflush(uint32_t aSize)
    1299                 : {
    1300               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1301                 :     // Only assert plugin thread here for consistency with in-process plugins.
    1302               0 :     AssertPluginThread();
    1303               0 :     return 0;
    1304                 : }
    1305                 : 
    1306                 : void NP_CALLBACK
    1307               0 : _reloadplugins(NPBool aReloadPages)
    1308                 : {
    1309               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1310               0 :     ENSURE_PLUGIN_THREAD_VOID();
    1311               0 :     NS_WARNING("Not yet implemented!");
    1312                 : }
    1313                 : 
    1314                 : void NP_CALLBACK
    1315               0 : _invalidaterect(NPP aNPP,
    1316                 :                 NPRect* aInvalidRect)
    1317                 : {
    1318               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1319               0 :     ENSURE_PLUGIN_THREAD_VOID();
    1320                 :     // NULL check for nspluginwrapper (bug 548434)
    1321               0 :     if (aNPP) {
    1322               0 :         InstCast(aNPP)->InvalidateRect(aInvalidRect);
    1323                 :     }
    1324                 : }
    1325                 : 
    1326                 : void NP_CALLBACK
    1327               0 : _invalidateregion(NPP aNPP,
    1328                 :                   NPRegion aInvalidRegion)
    1329                 : {
    1330               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1331               0 :     ENSURE_PLUGIN_THREAD_VOID();
    1332               0 :     NS_WARNING("Not yet implemented!");
    1333                 : }
    1334                 : 
    1335                 : void NP_CALLBACK
    1336               0 : _forceredraw(NPP aNPP)
    1337                 : {
    1338               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1339               0 :     ENSURE_PLUGIN_THREAD_VOID();
    1340                 : 
    1341                 :     // We ignore calls to NPN_ForceRedraw. Such calls should
    1342                 :     // never be necessary.
    1343                 : }
    1344                 : 
    1345                 : const char* NP_CALLBACK
    1346               0 : _useragent(NPP aNPP)
    1347                 : {
    1348               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1349               0 :     ENSURE_PLUGIN_THREAD(nsnull);
    1350               0 :     return PluginModuleChild::current()->GetUserAgent();
    1351                 : }
    1352                 : 
    1353                 : void* NP_CALLBACK
    1354               0 : _memalloc(uint32_t aSize)
    1355                 : {
    1356               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1357                 :     // Only assert plugin thread here for consistency with in-process plugins.
    1358               0 :     AssertPluginThread();
    1359               0 :     return NS_Alloc(aSize);
    1360                 : }
    1361                 : 
    1362                 : // Deprecated entry points for the old Java plugin.
    1363                 : void* NP_CALLBACK /* OJI type: JRIEnv* */
    1364               0 : _getjavaenv(void)
    1365                 : {
    1366               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1367               0 :     return 0;
    1368                 : }
    1369                 : 
    1370                 : void* NP_CALLBACK /* OJI type: jref */
    1371               0 : _getjavapeer(NPP aNPP)
    1372                 : {
    1373               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1374               0 :     return 0;
    1375                 : }
    1376                 : 
    1377                 : bool NP_CALLBACK
    1378               0 : _invoke(NPP aNPP,
    1379                 :         NPObject* aNPObj,
    1380                 :         NPIdentifier aMethod,
    1381                 :         const NPVariant* aArgs,
    1382                 :         uint32_t aArgCount,
    1383                 :         NPVariant* aResult)
    1384                 : {
    1385               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1386               0 :     ENSURE_PLUGIN_THREAD(false);
    1387                 : 
    1388               0 :     if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->invoke)
    1389               0 :         return false;
    1390                 : 
    1391               0 :     return aNPObj->_class->invoke(aNPObj, aMethod, aArgs, aArgCount, aResult);
    1392                 : }
    1393                 : 
    1394                 : bool NP_CALLBACK
    1395               0 : _invokedefault(NPP aNPP,
    1396                 :                NPObject* aNPObj,
    1397                 :                const NPVariant* aArgs,
    1398                 :                uint32_t aArgCount,
    1399                 :                NPVariant* aResult)
    1400                 : {
    1401               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1402               0 :     ENSURE_PLUGIN_THREAD(false);
    1403                 : 
    1404               0 :     if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->invokeDefault)
    1405               0 :         return false;
    1406                 : 
    1407               0 :     return aNPObj->_class->invokeDefault(aNPObj, aArgs, aArgCount, aResult);
    1408                 : }
    1409                 : 
    1410                 : bool NP_CALLBACK
    1411               0 : _evaluate(NPP aNPP,
    1412                 :           NPObject* aObject,
    1413                 :           NPString* aScript,
    1414                 :           NPVariant* aResult)
    1415                 : {
    1416               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1417               0 :     ENSURE_PLUGIN_THREAD(false);
    1418                 : 
    1419               0 :     if (!(aNPP && aObject && aScript && aResult)) {
    1420               0 :         NS_ERROR("Bad arguments!");
    1421               0 :         return false;
    1422                 :     }
    1423                 : 
    1424                 :     PluginScriptableObjectChild* actor =
    1425               0 :       InstCast(aNPP)->GetActorForNPObject(aObject);
    1426               0 :     if (!actor) {
    1427               0 :         NS_ERROR("Failed to create actor?!");
    1428               0 :         return false;
    1429                 :     }
    1430                 : 
    1431                 : #ifdef XP_WIN
    1432                 :     if (gDelayFlashFocusReplyUntilEval) {
    1433                 :         ReplyMessage(0);
    1434                 :         gDelayFlashFocusReplyUntilEval = false;
    1435                 :     }
    1436                 : #endif
    1437                 : 
    1438               0 :     return actor->Evaluate(aScript, aResult);
    1439                 : }
    1440                 : 
    1441                 : bool NP_CALLBACK
    1442               0 : _getproperty(NPP aNPP,
    1443                 :              NPObject* aNPObj,
    1444                 :              NPIdentifier aPropertyName,
    1445                 :              NPVariant* aResult)
    1446                 : {
    1447               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1448               0 :     ENSURE_PLUGIN_THREAD(false);
    1449                 : 
    1450               0 :     if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->getProperty)
    1451               0 :         return false;
    1452                 : 
    1453               0 :     return aNPObj->_class->getProperty(aNPObj, aPropertyName, aResult);
    1454                 : }
    1455                 : 
    1456                 : bool NP_CALLBACK
    1457               0 : _setproperty(NPP aNPP,
    1458                 :              NPObject* aNPObj,
    1459                 :              NPIdentifier aPropertyName,
    1460                 :              const NPVariant* aValue)
    1461                 : {
    1462               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1463               0 :     ENSURE_PLUGIN_THREAD(false);
    1464                 : 
    1465               0 :     if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->setProperty)
    1466               0 :         return false;
    1467                 : 
    1468               0 :     return aNPObj->_class->setProperty(aNPObj, aPropertyName, aValue);
    1469                 : }
    1470                 : 
    1471                 : bool NP_CALLBACK
    1472               0 : _removeproperty(NPP aNPP,
    1473                 :                 NPObject* aNPObj,
    1474                 :                 NPIdentifier aPropertyName)
    1475                 : {
    1476               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1477               0 :     ENSURE_PLUGIN_THREAD(false);
    1478                 : 
    1479               0 :     if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->removeProperty)
    1480               0 :         return false;
    1481                 : 
    1482               0 :     return aNPObj->_class->removeProperty(aNPObj, aPropertyName);
    1483                 : }
    1484                 : 
    1485                 : bool NP_CALLBACK
    1486               0 : _hasproperty(NPP aNPP,
    1487                 :              NPObject* aNPObj,
    1488                 :              NPIdentifier aPropertyName)
    1489                 : {
    1490               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1491               0 :     ENSURE_PLUGIN_THREAD(false);
    1492                 : 
    1493               0 :     if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->hasProperty)
    1494               0 :         return false;
    1495                 : 
    1496               0 :     return aNPObj->_class->hasProperty(aNPObj, aPropertyName);
    1497                 : }
    1498                 : 
    1499                 : bool NP_CALLBACK
    1500               0 : _hasmethod(NPP aNPP,
    1501                 :            NPObject* aNPObj,
    1502                 :            NPIdentifier aMethodName)
    1503                 : {
    1504               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1505               0 :     ENSURE_PLUGIN_THREAD(false);
    1506                 : 
    1507               0 :     if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->hasMethod)
    1508               0 :         return false;
    1509                 : 
    1510               0 :     return aNPObj->_class->hasMethod(aNPObj, aMethodName);
    1511                 : }
    1512                 : 
    1513                 : bool NP_CALLBACK
    1514               0 : _enumerate(NPP aNPP,
    1515                 :            NPObject* aNPObj,
    1516                 :            NPIdentifier** aIdentifiers,
    1517                 :            uint32_t* aCount)
    1518                 : {
    1519               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1520               0 :     ENSURE_PLUGIN_THREAD(false);
    1521                 : 
    1522               0 :     if (!aNPP || !aNPObj || !aNPObj->_class)
    1523               0 :         return false;
    1524                 : 
    1525               0 :     if (!NP_CLASS_STRUCT_VERSION_HAS_ENUM(aNPObj->_class) ||
    1526               0 :         !aNPObj->_class->enumerate) {
    1527               0 :         *aIdentifiers = 0;
    1528               0 :         *aCount = 0;
    1529               0 :         return true;
    1530                 :     }
    1531                 : 
    1532               0 :     return aNPObj->_class->enumerate(aNPObj, aIdentifiers, aCount);
    1533                 : }
    1534                 : 
    1535                 : bool NP_CALLBACK
    1536               0 : _construct(NPP aNPP,
    1537                 :            NPObject* aNPObj,
    1538                 :            const NPVariant* aArgs,
    1539                 :            uint32_t aArgCount,
    1540                 :            NPVariant* aResult)
    1541                 : {
    1542               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1543               0 :     ENSURE_PLUGIN_THREAD(false);
    1544                 : 
    1545               0 :     if (!aNPP || !aNPObj || !aNPObj->_class ||
    1546               0 :         !NP_CLASS_STRUCT_VERSION_HAS_CTOR(aNPObj->_class) ||
    1547               0 :         !aNPObj->_class->construct) {
    1548               0 :         return false;
    1549                 :     }
    1550                 : 
    1551               0 :     return aNPObj->_class->construct(aNPObj, aArgs, aArgCount, aResult);
    1552                 : }
    1553                 : 
    1554                 : void NP_CALLBACK
    1555               0 : _releasevariantvalue(NPVariant* aVariant)
    1556                 : {
    1557               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1558                 :     // Only assert plugin thread here for consistency with in-process plugins.
    1559               0 :     AssertPluginThread();
    1560                 : 
    1561               0 :     if (NPVARIANT_IS_STRING(*aVariant)) {
    1562               0 :         NPString str = NPVARIANT_TO_STRING(*aVariant);
    1563               0 :         free(const_cast<NPUTF8*>(str.UTF8Characters));
    1564                 :     }
    1565               0 :     else if (NPVARIANT_IS_OBJECT(*aVariant)) {
    1566               0 :         NPObject* object = NPVARIANT_TO_OBJECT(*aVariant);
    1567               0 :         if (object) {
    1568               0 :             PluginModuleChild::NPN_ReleaseObject(object);
    1569                 :         }
    1570                 :     }
    1571               0 :     VOID_TO_NPVARIANT(*aVariant);
    1572               0 : }
    1573                 : 
    1574                 : void NP_CALLBACK
    1575               0 : _setexception(NPObject* aNPObj,
    1576                 :               const NPUTF8* aMessage)
    1577                 : {
    1578               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1579               0 :     ENSURE_PLUGIN_THREAD_VOID();
    1580                 : 
    1581               0 :     PluginModuleChild* self = PluginModuleChild::current();
    1582               0 :     PluginScriptableObjectChild* actor = NULL;
    1583               0 :     if (aNPObj) {
    1584               0 :         actor = self->GetActorForNPObject(aNPObj);
    1585               0 :         if (!actor) {
    1586               0 :             NS_ERROR("Failed to get actor!");
    1587               0 :             return;
    1588                 :         }
    1589                 :     }
    1590                 : 
    1591                 :     self->SendNPN_SetException(static_cast<PPluginScriptableObjectChild*>(actor),
    1592               0 :                                NullableString(aMessage));
    1593                 : }
    1594                 : 
    1595                 : void NP_CALLBACK
    1596               0 : _pushpopupsenabledstate(NPP aNPP,
    1597                 :                         NPBool aEnabled)
    1598                 : {
    1599               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1600               0 :     ENSURE_PLUGIN_THREAD_VOID();
    1601                 : 
    1602               0 :     InstCast(aNPP)->CallNPN_PushPopupsEnabledState(aEnabled ? true : false);
    1603                 : }
    1604                 : 
    1605                 : void NP_CALLBACK
    1606               0 : _poppopupsenabledstate(NPP aNPP)
    1607                 : {
    1608               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1609               0 :     ENSURE_PLUGIN_THREAD_VOID();
    1610                 : 
    1611               0 :     InstCast(aNPP)->CallNPN_PopPopupsEnabledState();
    1612                 : }
    1613                 : 
    1614                 : void NP_CALLBACK
    1615               0 : _pluginthreadasynccall(NPP aNPP,
    1616                 :                        PluginThreadCallback aFunc,
    1617                 :                        void* aUserData)
    1618                 : {
    1619               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1620               0 :     if (!aFunc)
    1621               0 :         return;
    1622                 : 
    1623               0 :     InstCast(aNPP)->AsyncCall(aFunc, aUserData);
    1624                 : }
    1625                 : 
    1626                 : NPError NP_CALLBACK
    1627               0 : _getvalueforurl(NPP npp, NPNURLVariable variable, const char *url,
    1628                 :                 char **value, uint32_t *len)
    1629                 : {
    1630               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1631               0 :     AssertPluginThread();
    1632                 : 
    1633               0 :     if (!url)
    1634               0 :         return NPERR_INVALID_URL;
    1635                 : 
    1636               0 :     if (!npp || !value || !len)
    1637               0 :         return NPERR_INVALID_PARAM;
    1638                 : 
    1639               0 :     switch (variable) {
    1640                 :     case NPNURLVCookie:
    1641                 :     case NPNURLVProxy:
    1642               0 :         nsCString v;
    1643                 :         NPError result;
    1644               0 :         InstCast(npp)->
    1645               0 :             CallNPN_GetValueForURL(variable, nsCString(url), &v, &result);
    1646               0 :         if (NPERR_NO_ERROR == result) {
    1647               0 :             *value = ToNewCString(v);
    1648               0 :             *len = v.Length();
    1649                 :         }
    1650               0 :         return result;
    1651                 :     }
    1652                 : 
    1653               0 :     return NPERR_INVALID_PARAM;
    1654                 : }
    1655                 : 
    1656                 : NPError NP_CALLBACK
    1657               0 : _setvalueforurl(NPP npp, NPNURLVariable variable, const char *url,
    1658                 :                 const char *value, uint32_t len)
    1659                 : {
    1660               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1661               0 :     AssertPluginThread();
    1662                 : 
    1663               0 :     if (!value)
    1664               0 :         return NPERR_INVALID_PARAM;
    1665                 : 
    1666               0 :     if (!url)
    1667               0 :         return NPERR_INVALID_URL;
    1668                 : 
    1669               0 :     switch (variable) {
    1670                 :     case NPNURLVCookie:
    1671                 :     case NPNURLVProxy:
    1672                 :         NPError result;
    1673               0 :         InstCast(npp)->CallNPN_SetValueForURL(variable, nsCString(url),
    1674               0 :                                               nsDependentCString(value, len),
    1675               0 :                                               &result);
    1676               0 :         return result;
    1677                 :     }
    1678                 : 
    1679               0 :     return NPERR_INVALID_PARAM;
    1680                 : }
    1681                 : 
    1682                 : NPError NP_CALLBACK
    1683               0 : _getauthenticationinfo(NPP npp, const char *protocol,
    1684                 :                        const char *host, int32_t port,
    1685                 :                        const char *scheme, const char *realm,
    1686                 :                        char **username, uint32_t *ulen,
    1687                 :                        char **password, uint32_t *plen)
    1688                 : {
    1689               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1690               0 :     AssertPluginThread();
    1691                 : 
    1692               0 :     if (!protocol || !host || !scheme || !realm || !username || !ulen ||
    1693                 :         !password || !plen)
    1694               0 :         return NPERR_INVALID_PARAM;
    1695                 : 
    1696               0 :     nsCString u;
    1697               0 :     nsCString p;
    1698                 :     NPError result;
    1699               0 :     InstCast(npp)->
    1700               0 :         CallNPN_GetAuthenticationInfo(nsDependentCString(protocol),
    1701               0 :                                       nsDependentCString(host),
    1702                 :                                       port,
    1703               0 :                                       nsDependentCString(scheme),
    1704               0 :                                       nsDependentCString(realm),
    1705               0 :                                       &u, &p, &result);
    1706               0 :     if (NPERR_NO_ERROR == result) {
    1707               0 :         *username = ToNewCString(u);
    1708               0 :         *ulen = u.Length();
    1709               0 :         *password = ToNewCString(p);
    1710               0 :         *plen = p.Length();
    1711                 :     }
    1712               0 :     return result;
    1713                 : }
    1714                 : 
    1715                 : uint32_t NP_CALLBACK
    1716               0 : _scheduletimer(NPP npp, uint32_t interval, NPBool repeat,
    1717                 :                void (*timerFunc)(NPP npp, uint32_t timerID))
    1718                 : {
    1719               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1720               0 :     AssertPluginThread();
    1721               0 :     return InstCast(npp)->ScheduleTimer(interval, repeat, timerFunc);
    1722                 : }
    1723                 : 
    1724                 : void NP_CALLBACK
    1725               0 : _unscheduletimer(NPP npp, uint32_t timerID)
    1726                 : {
    1727               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1728               0 :     AssertPluginThread();
    1729               0 :     InstCast(npp)->UnscheduleTimer(timerID);
    1730               0 : }
    1731                 : 
    1732                 : 
    1733                 : #ifdef OS_MACOSX
    1734                 : static void ProcessBrowserEvents(void* pluginModule) {
    1735                 :     PluginModuleChild* pmc = static_cast<PluginModuleChild*>(pluginModule);
    1736                 : 
    1737                 :     if (!pmc)
    1738                 :         return;
    1739                 : 
    1740                 :     pmc->CallProcessSomeEvents();
    1741                 : }
    1742                 : #endif
    1743                 : 
    1744                 : NPError NP_CALLBACK
    1745               0 : _popupcontextmenu(NPP instance, NPMenu* menu)
    1746                 : {
    1747               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1748               0 :     AssertPluginThread();
    1749                 : 
    1750                 : #ifdef MOZ_WIDGET_COCOA
    1751                 :     double pluginX, pluginY; 
    1752                 :     double screenX, screenY;
    1753                 : 
    1754                 :     const NPCocoaEvent* currentEvent = InstCast(instance)->getCurrentEvent();
    1755                 :     if (!currentEvent) {
    1756                 :         return NPERR_GENERIC_ERROR;
    1757                 :     }
    1758                 : 
    1759                 :     // Ensure that the events has an x/y value.
    1760                 :     if (currentEvent->type != NPCocoaEventMouseDown    &&
    1761                 :         currentEvent->type != NPCocoaEventMouseUp      &&
    1762                 :         currentEvent->type != NPCocoaEventMouseMoved   &&
    1763                 :         currentEvent->type != NPCocoaEventMouseEntered &&
    1764                 :         currentEvent->type != NPCocoaEventMouseExited  &&
    1765                 :         currentEvent->type != NPCocoaEventMouseDragged) {
    1766                 :         return NPERR_GENERIC_ERROR;
    1767                 :     }
    1768                 : 
    1769                 :     pluginX = currentEvent->data.mouse.pluginX;
    1770                 :     pluginY = currentEvent->data.mouse.pluginY;
    1771                 : 
    1772                 :     if ((pluginX < 0.0) || (pluginY < 0.0))
    1773                 :         return NPERR_GENERIC_ERROR;
    1774                 : 
    1775                 :     NPBool success = _convertpoint(instance, 
    1776                 :                                   pluginX,  pluginY, NPCoordinateSpacePlugin, 
    1777                 :                                  &screenX, &screenY, NPCoordinateSpaceScreen);
    1778                 : 
    1779                 :     if (success) {
    1780                 :         return mozilla::plugins::PluginUtilsOSX::ShowCocoaContextMenu(menu,
    1781                 :                                     screenX, screenY,
    1782                 :                                     PluginModuleChild::current(),
    1783                 :                                     ProcessBrowserEvents);
    1784                 :     } else {
    1785                 :         NS_WARNING("Convertpoint failed, could not created contextmenu.");
    1786                 :         return NPERR_GENERIC_ERROR;
    1787                 :     }
    1788                 : 
    1789                 : #else
    1790               0 :     NS_WARNING("Not supported on this platform!");
    1791               0 :     return NPERR_GENERIC_ERROR;
    1792                 : #endif
    1793                 : }
    1794                 : 
    1795                 : NPBool NP_CALLBACK
    1796               0 : _convertpoint(NPP instance, 
    1797                 :               double sourceX, double sourceY, NPCoordinateSpace sourceSpace,
    1798                 :               double *destX, double *destY, NPCoordinateSpace destSpace)
    1799                 : {
    1800               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1801               0 :     AssertPluginThread();
    1802                 : 
    1803               0 :     double rDestX = 0;
    1804               0 :     bool ignoreDestX = !destX;
    1805               0 :     double rDestY = 0;
    1806               0 :     bool ignoreDestY = !destY;
    1807               0 :     bool result = false;
    1808               0 :     InstCast(instance)->CallNPN_ConvertPoint(sourceX, ignoreDestX, sourceY, ignoreDestY, sourceSpace, destSpace,
    1809               0 :                                              &rDestX,  &rDestY, &result);
    1810               0 :     if (result) {
    1811               0 :         if (destX)
    1812               0 :             *destX = rDestX;
    1813               0 :         if (destY)
    1814               0 :             *destY = rDestY;
    1815                 :     }
    1816                 : 
    1817               0 :     return result;
    1818                 : }
    1819                 : 
    1820                 : void NP_CALLBACK
    1821               0 : _urlredirectresponse(NPP instance, void* notifyData, NPBool allow)
    1822                 : {
    1823               0 :     InstCast(instance)->NPN_URLRedirectResponse(notifyData, allow);
    1824               0 : }
    1825                 : 
    1826                 : NPError NP_CALLBACK
    1827               0 : _initasyncsurface(NPP instance, NPSize *size,
    1828                 :                   NPImageFormat format, void *initData,
    1829                 :                   NPAsyncSurface *surface)
    1830                 : {
    1831               0 :     return InstCast(instance)->NPN_InitAsyncSurface(size, format, initData, surface);
    1832                 : }
    1833                 : 
    1834                 : NPError NP_CALLBACK
    1835               0 : _finalizeasyncsurface(NPP instance, NPAsyncSurface *surface)
    1836                 : {
    1837               0 :     return InstCast(instance)->NPN_FinalizeAsyncSurface(surface);
    1838                 : }
    1839                 : 
    1840                 : void NP_CALLBACK
    1841               0 : _setcurrentasyncsurface(NPP instance, NPAsyncSurface *surface, NPRect *changed)
    1842                 : {
    1843               0 :     InstCast(instance)->NPN_SetCurrentAsyncSurface(surface, changed);
    1844               0 : }
    1845                 : 
    1846                 : } /* namespace child */
    1847                 : } /* namespace plugins */
    1848                 : } /* namespace mozilla */
    1849                 : 
    1850                 : //-----------------------------------------------------------------------------
    1851                 : 
    1852                 : bool
    1853               0 : PluginModuleChild::AnswerNP_GetEntryPoints(NPError* _retval)
    1854                 : {
    1855               0 :     PLUGIN_LOG_DEBUG_METHOD;
    1856               0 :     AssertPluginThread();
    1857                 : 
    1858                 : #if defined(OS_LINUX)
    1859               0 :     return true;
    1860                 : #elif defined(OS_WIN) || defined(OS_MACOSX)
    1861                 :     *_retval = mGetEntryPointsFunc(&mFunctions);
    1862                 :     return true;
    1863                 : #else
    1864                 : #  error Please implement me for your platform
    1865                 : #endif
    1866                 : }
    1867                 : 
    1868                 : bool
    1869               0 : PluginModuleChild::AnswerNP_Initialize(const uint32_t& aFlags, NPError* _retval)
    1870                 : {
    1871               0 :     PLUGIN_LOG_DEBUG_METHOD;
    1872               0 :     AssertPluginThread();
    1873                 : 
    1874               0 :     mAsyncDrawingAllowed = aFlags & kAllowAsyncDrawing;
    1875                 : 
    1876                 : #ifdef OS_WIN
    1877                 :     SetEventHooks();
    1878                 : #endif
    1879                 : 
    1880                 : #ifdef MOZ_X11
    1881                 :     // Send the parent a dup of our X socket, to act as a proxy
    1882                 :     // reference for our X resources
    1883               0 :     int xSocketFd = ConnectionNumber(DefaultXDisplay());
    1884               0 :     SendBackUpXResources(FileDescriptor(xSocketFd, false/*don't close*/));
    1885                 : #endif
    1886                 : 
    1887                 : #if defined(OS_LINUX)
    1888               0 :     *_retval = mInitializeFunc(&sBrowserFuncs, &mFunctions);
    1889               0 :     return true;
    1890                 : #elif defined(OS_WIN) || defined(OS_MACOSX)
    1891                 :     *_retval = mInitializeFunc(&sBrowserFuncs);
    1892                 :     return true;
    1893                 : #else
    1894                 : #  error Please implement me for your platform
    1895                 : #endif
    1896                 : }
    1897                 : 
    1898                 : PPluginIdentifierChild*
    1899               0 : PluginModuleChild::AllocPPluginIdentifier(const nsCString& aString,
    1900                 :                                           const int32_t& aInt,
    1901                 :                                           const bool& aTemporary)
    1902                 : {
    1903                 :     // We cannot call SetPermanent within this function because Manager() isn't
    1904                 :     // set up yet.
    1905               0 :     if (aString.IsVoid()) {
    1906               0 :         return new PluginIdentifierChildInt(aInt);
    1907                 :     }
    1908               0 :     return new PluginIdentifierChildString(aString);
    1909                 : }
    1910                 : 
    1911                 : bool
    1912               0 : PluginModuleChild::RecvPPluginIdentifierConstructor(PPluginIdentifierChild* actor,
    1913                 :                                                     const nsCString& aString,
    1914                 :                                                     const int32_t& aInt,
    1915                 :                                                     const bool& aTemporary)
    1916                 : {
    1917               0 :     if (!aTemporary) {
    1918               0 :         static_cast<PluginIdentifierChild*>(actor)->MakePermanent();
    1919                 :     }
    1920               0 :     return true;
    1921                 : }
    1922                 : 
    1923                 : bool
    1924               0 : PluginModuleChild::DeallocPPluginIdentifier(PPluginIdentifierChild* aActor)
    1925                 : {
    1926               0 :     delete aActor;
    1927               0 :     return true;
    1928                 : }
    1929                 : 
    1930                 : #if defined(XP_WIN)
    1931                 : BOOL WINAPI
    1932                 : PMCGetWindowInfoHook(HWND hWnd, PWINDOWINFO pwi)
    1933                 : {
    1934                 :   if (!pwi)
    1935                 :       return FALSE;
    1936                 : 
    1937                 :   if (!sGetWindowInfoPtrStub) {
    1938                 :      NS_ASSERTION(FALSE, "Something is horribly wrong in PMCGetWindowInfoHook!");
    1939                 :      return FALSE;
    1940                 :   }
    1941                 : 
    1942                 :   if (!sBrowserHwnd) {
    1943                 :       PRUnichar szClass[20];
    1944                 :       if (GetClassNameW(hWnd, szClass, ArrayLength(szClass)) &&
    1945                 :           !wcscmp(szClass, kMozillaWindowClass)) {
    1946                 :           sBrowserHwnd = hWnd;
    1947                 :       }
    1948                 :   }
    1949                 :   // Oddity: flash does strange rect comparisons for mouse input destined for
    1950                 :   // it's internal settings window. Post removing sub widgets for tabs, touch
    1951                 :   // this up so they get the rect they expect.
    1952                 :   // XXX potentially tie this to a specific major version?
    1953                 :   BOOL result = sGetWindowInfoPtrStub(hWnd, pwi);
    1954                 :   if (sBrowserHwnd && sBrowserHwnd == hWnd)
    1955                 :       pwi->rcWindow = pwi->rcClient;
    1956                 :   return result;
    1957                 : }
    1958                 : #endif
    1959                 : 
    1960                 : PPluginInstanceChild*
    1961               0 : PluginModuleChild::AllocPPluginInstance(const nsCString& aMimeType,
    1962                 :                                         const uint16_t& aMode,
    1963                 :                                         const InfallibleTArray<nsCString>& aNames,
    1964                 :                                         const InfallibleTArray<nsCString>& aValues,
    1965                 :                                         NPError* rv)
    1966                 : {
    1967               0 :     PLUGIN_LOG_DEBUG_METHOD;
    1968               0 :     AssertPluginThread();
    1969                 : 
    1970               0 :     InitQuirksModes(aMimeType);
    1971                 : 
    1972                 : #ifdef XP_WIN
    1973                 :     if ((mQuirks & QUIRK_FLASH_HOOK_GETWINDOWINFO) &&
    1974                 :         !sGetWindowInfoPtrStub) {
    1975                 :         sUser32Intercept.Init("user32.dll");
    1976                 :         sUser32Intercept.AddHook("GetWindowInfo", reinterpret_cast<intptr_t>(PMCGetWindowInfoHook),
    1977                 :                                  (void**) &sGetWindowInfoPtrStub);
    1978                 :     }
    1979                 : #endif
    1980                 : 
    1981                 :     nsAutoPtr<PluginInstanceChild> childInstance(
    1982               0 :         new PluginInstanceChild(&mFunctions));
    1983               0 :     if (!childInstance->Initialize()) {
    1984               0 :         *rv = NPERR_GENERIC_ERROR;
    1985               0 :         return 0;
    1986                 :     }
    1987               0 :     return childInstance.forget();
    1988                 : }
    1989                 : 
    1990                 : void
    1991               0 : PluginModuleChild::InitQuirksModes(const nsCString& aMimeType)
    1992                 : {
    1993               0 :     if (mQuirks != QUIRKS_NOT_INITIALIZED)
    1994               0 :       return;
    1995               0 :     mQuirks = 0;
    1996                 :     // application/x-silverlight
    1997                 :     // application/x-silverlight-2
    1998               0 :     NS_NAMED_LITERAL_CSTRING(silverlight, "application/x-silverlight");
    1999               0 :     if (FindInReadable(silverlight, aMimeType)) {
    2000               0 :         mQuirks |= QUIRK_SILVERLIGHT_DEFAULT_TRANSPARENT;
    2001                 : #ifdef OS_WIN
    2002                 :         mQuirks |= QUIRK_WINLESS_TRACKPOPUP_HOOK;
    2003                 :         mQuirks |= QUIRK_SILVERLIGHT_FOCUS_CHECK_PARENT;
    2004                 : #endif
    2005                 :     }
    2006                 : 
    2007                 : #ifdef OS_WIN
    2008                 :     // application/x-shockwave-flash
    2009                 :     NS_NAMED_LITERAL_CSTRING(flash, "application/x-shockwave-flash");
    2010                 :     if (FindInReadable(flash, aMimeType)) {
    2011                 :         mQuirks |= QUIRK_WINLESS_TRACKPOPUP_HOOK;
    2012                 :         mQuirks |= QUIRK_FLASH_THROTTLE_WMUSER_EVENTS; 
    2013                 :         mQuirks |= QUIRK_FLASH_HOOK_SETLONGPTR;
    2014                 :         mQuirks |= QUIRK_FLASH_HOOK_GETWINDOWINFO;
    2015                 :         mQuirks |= QUIRK_FLASH_FIXUP_MOUSE_CAPTURE;
    2016                 :     }
    2017                 : 
    2018                 :     // QuickTime plugin usually loaded with audio/mpeg mimetype
    2019                 :     NS_NAMED_LITERAL_CSTRING(quicktime, "npqtplugin");
    2020                 :     if (FindInReadable(quicktime, mPluginFilename)) {
    2021                 :       mQuirks |= QUIRK_QUICKTIME_AVOID_SETWINDOW;
    2022                 :     }
    2023                 : #endif
    2024                 : 
    2025                 : #ifdef XP_MACOSX
    2026                 :     // Whitelist Flash and Quicktime to support offline renderer
    2027                 :     NS_NAMED_LITERAL_CSTRING(flash, "application/x-shockwave-flash");
    2028                 :     NS_NAMED_LITERAL_CSTRING(quicktime, "QuickTime Plugin.plugin");
    2029                 :     if (FindInReadable(flash, aMimeType) ||
    2030                 :         FindInReadable(quicktime, mPluginFilename)) {
    2031                 :         mQuirks |= QUIRK_ALLOW_OFFLINE_RENDERER;
    2032                 :     }
    2033                 : #endif
    2034                 : }
    2035                 : 
    2036                 : bool
    2037               0 : PluginModuleChild::AnswerPPluginInstanceConstructor(PPluginInstanceChild* aActor,
    2038                 :                                                     const nsCString& aMimeType,
    2039                 :                                                     const uint16_t& aMode,
    2040                 :                                                     const InfallibleTArray<nsCString>& aNames,
    2041                 :                                                     const InfallibleTArray<nsCString>& aValues,
    2042                 :                                                     NPError* rv)
    2043                 : {
    2044               0 :     PLUGIN_LOG_DEBUG_METHOD;
    2045               0 :     AssertPluginThread();
    2046                 : 
    2047                 :     PluginInstanceChild* childInstance =
    2048               0 :         reinterpret_cast<PluginInstanceChild*>(aActor);
    2049               0 :     NS_ASSERTION(childInstance, "Null actor!");
    2050                 : 
    2051                 :     // unpack the arguments into a C format
    2052               0 :     int argc = aNames.Length();
    2053               0 :     NS_ASSERTION(argc == (int) aValues.Length(),
    2054                 :                  "argn.length != argv.length");
    2055                 : 
    2056               0 :     nsAutoArrayPtr<char*> argn(new char*[1 + argc]);
    2057               0 :     nsAutoArrayPtr<char*> argv(new char*[1 + argc]);
    2058               0 :     argn[argc] = 0;
    2059               0 :     argv[argc] = 0;
    2060                 : 
    2061               0 :     for (int i = 0; i < argc; ++i) {
    2062               0 :         argn[i] = const_cast<char*>(NullableStringGet(aNames[i]));
    2063               0 :         argv[i] = const_cast<char*>(NullableStringGet(aValues[i]));
    2064                 :     }
    2065                 : 
    2066               0 :     NPP npp = childInstance->GetNPP();
    2067                 : 
    2068                 :     // FIXME/cjones: use SAFE_CALL stuff
    2069               0 :     *rv = mFunctions.newp((char*)NullableStringGet(aMimeType),
    2070                 :                           npp,
    2071                 :                           aMode,
    2072                 :                           argc,
    2073                 :                           argn,
    2074                 :                           argv,
    2075               0 :                           0);
    2076               0 :     if (NPERR_NO_ERROR != *rv) {
    2077               0 :         return true;
    2078                 :     }
    2079                 : 
    2080                 : #if defined(XP_MACOSX) && defined(__i386__)
    2081                 :     // If an i386 Mac OS X plugin has selected the Carbon event model then
    2082                 :     // we have to fail. We do not support putting Carbon event model plugins
    2083                 :     // out of process. Note that Carbon is the default model so out of process
    2084                 :     // plugins need to actively negotiate something else in order to work
    2085                 :     // out of process.
    2086                 :     if (childInstance->EventModel() == NPEventModelCarbon) {
    2087                 :       // Send notification that a plugin tried to negotiate Carbon NPAPI so that
    2088                 :       // users can be notified that restarting the browser in i386 mode may allow
    2089                 :       // them to use the plugin.
    2090                 :       childInstance->SendNegotiatedCarbon();
    2091                 : 
    2092                 :       // Fail to instantiate.
    2093                 :       *rv = NPERR_MODULE_LOAD_FAILED_ERROR;
    2094                 :     }
    2095                 : #endif
    2096                 : 
    2097               0 :     return true;
    2098                 : }
    2099                 : 
    2100                 : bool
    2101               0 : PluginModuleChild::DeallocPPluginInstance(PPluginInstanceChild* aActor)
    2102                 : {
    2103               0 :     PLUGIN_LOG_DEBUG_METHOD;
    2104               0 :     AssertPluginThread();
    2105                 : 
    2106               0 :     delete aActor;
    2107                 : 
    2108               0 :     return true;
    2109                 : }
    2110                 : 
    2111                 : NPObject* NP_CALLBACK
    2112               0 : PluginModuleChild::NPN_CreateObject(NPP aNPP, NPClass* aClass)
    2113                 : {
    2114               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    2115               0 :     ENSURE_PLUGIN_THREAD(nsnull);
    2116                 : 
    2117               0 :     PluginInstanceChild* i = InstCast(aNPP);
    2118               0 :     if (i->mDeletingHash) {
    2119               0 :         NS_ERROR("Plugin used NPP after NPP_Destroy");
    2120               0 :         return NULL;
    2121                 :     }
    2122                 : 
    2123                 :     NPObject* newObject;
    2124               0 :     if (aClass && aClass->allocate) {
    2125               0 :         newObject = aClass->allocate(aNPP, aClass);
    2126                 :     }
    2127                 :     else {
    2128               0 :         newObject = reinterpret_cast<NPObject*>(child::_memalloc(sizeof(NPObject)));
    2129                 :     }
    2130                 : 
    2131               0 :     if (newObject) {
    2132               0 :         newObject->_class = aClass;
    2133               0 :         newObject->referenceCount = 1;
    2134               0 :         NS_LOG_ADDREF(newObject, 1, "NPObject", sizeof(NPObject));
    2135                 :     }
    2136                 : 
    2137               0 :     NPObjectData* d = static_cast<PluginModuleChild*>(i->Manager())
    2138               0 :         ->mObjectMap.PutEntry(newObject);
    2139               0 :     NS_ASSERTION(!d->instance, "New NPObject already mapped?");
    2140               0 :     d->instance = i;
    2141                 : 
    2142               0 :     return newObject;
    2143                 : }
    2144                 : 
    2145                 : NPObject* NP_CALLBACK
    2146               0 : PluginModuleChild::NPN_RetainObject(NPObject* aNPObj)
    2147                 : {
    2148               0 :     AssertPluginThread();
    2149                 : 
    2150                 : #ifdef NS_BUILD_REFCNT_LOGGING
    2151                 :     int32_t refCnt =
    2152                 : #endif
    2153               0 :     PR_ATOMIC_INCREMENT((int32_t*)&aNPObj->referenceCount);
    2154               0 :     NS_LOG_ADDREF(aNPObj, refCnt, "NPObject", sizeof(NPObject));
    2155                 : 
    2156               0 :     return aNPObj;
    2157                 : }
    2158                 : 
    2159                 : void NP_CALLBACK
    2160               0 : PluginModuleChild::NPN_ReleaseObject(NPObject* aNPObj)
    2161                 : {
    2162               0 :     AssertPluginThread();
    2163                 : 
    2164               0 :     NPObjectData* d = current()->mObjectMap.GetEntry(aNPObj);
    2165               0 :     if (!d) {
    2166               0 :         NS_ERROR("Releasing object not in mObjectMap?");
    2167               0 :         return;
    2168                 :     }
    2169                 : 
    2170               0 :     DeletingObjectEntry* doe = NULL;
    2171               0 :     if (d->instance->mDeletingHash) {
    2172               0 :         doe = d->instance->mDeletingHash->GetEntry(aNPObj);
    2173               0 :         if (!doe) {
    2174               0 :             NS_ERROR("An object for a destroyed instance isn't in the instance deletion hash");
    2175               0 :             return;
    2176                 :         }
    2177               0 :         if (doe->mDeleted)
    2178               0 :             return;
    2179                 :     }
    2180                 : 
    2181               0 :     int32_t refCnt = PR_ATOMIC_DECREMENT((int32_t*)&aNPObj->referenceCount);
    2182               0 :     NS_LOG_RELEASE(aNPObj, refCnt, "NPObject");
    2183                 : 
    2184               0 :     if (refCnt == 0) {
    2185               0 :         DeallocNPObject(aNPObj);
    2186               0 :         if (doe)
    2187               0 :             doe->mDeleted = true;
    2188                 :     }
    2189               0 :     return;
    2190                 : }
    2191                 : 
    2192                 : void
    2193               0 : PluginModuleChild::DeallocNPObject(NPObject* aNPObj)
    2194                 : {
    2195               0 :     if (aNPObj->_class && aNPObj->_class->deallocate) {
    2196               0 :         aNPObj->_class->deallocate(aNPObj);
    2197                 :     } else {
    2198               0 :         child::_memfree(aNPObj);
    2199                 :     }
    2200                 : 
    2201               0 :     NPObjectData* d = current()->mObjectMap.GetEntry(aNPObj);
    2202               0 :     if (d->actor)
    2203               0 :         d->actor->NPObjectDestroyed();
    2204                 : 
    2205               0 :     current()->mObjectMap.RemoveEntry(aNPObj);
    2206               0 : }
    2207                 : 
    2208                 : void
    2209               0 : PluginModuleChild::FindNPObjectsForInstance(PluginInstanceChild* instance)
    2210                 : {
    2211               0 :     NS_ASSERTION(instance->mDeletingHash, "filling null mDeletingHash?");
    2212               0 :     mObjectMap.EnumerateEntries(CollectForInstance, instance);
    2213               0 : }
    2214                 : 
    2215                 : PLDHashOperator
    2216               0 : PluginModuleChild::CollectForInstance(NPObjectData* d, void* userArg)
    2217                 : {
    2218               0 :     PluginInstanceChild* instance = static_cast<PluginInstanceChild*>(userArg);
    2219               0 :     if (d->instance == instance) {
    2220               0 :         NPObject* o = d->GetKey();
    2221               0 :         instance->mDeletingHash->PutEntry(o);
    2222                 :     }
    2223               0 :     return PL_DHASH_NEXT;
    2224                 : }
    2225                 : 
    2226                 : NPIdentifier NP_CALLBACK
    2227               0 : PluginModuleChild::NPN_GetStringIdentifier(const NPUTF8* aName)
    2228                 : {
    2229               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    2230               0 :     AssertPluginThread();
    2231                 : 
    2232               0 :     if (!aName)
    2233               0 :         return 0;
    2234                 : 
    2235               0 :     PluginModuleChild* self = PluginModuleChild::current();
    2236               0 :     nsDependentCString name(aName);
    2237                 : 
    2238               0 :     PluginIdentifierChildString* ident = self->mStringIdentifiers.Get(name);
    2239               0 :     if (!ident) {
    2240               0 :         nsCString nameCopy(name);
    2241                 : 
    2242               0 :         ident = new PluginIdentifierChildString(nameCopy);
    2243               0 :         self->SendPPluginIdentifierConstructor(ident, nameCopy, -1, false);
    2244                 :     }
    2245               0 :     ident->MakePermanent();
    2246               0 :     return ident;
    2247                 : }
    2248                 : 
    2249                 : void NP_CALLBACK
    2250               0 : PluginModuleChild::NPN_GetStringIdentifiers(const NPUTF8** aNames,
    2251                 :                                             int32_t aNameCount,
    2252                 :                                             NPIdentifier* aIdentifiers)
    2253                 : {
    2254               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    2255               0 :     AssertPluginThread();
    2256                 : 
    2257               0 :     if (!(aNames && aNameCount > 0 && aIdentifiers)) {
    2258               0 :         NS_RUNTIMEABORT("Bad input! Headed for a crash!");
    2259                 :     }
    2260                 : 
    2261               0 :     PluginModuleChild* self = PluginModuleChild::current();
    2262                 : 
    2263               0 :     for (int32_t index = 0; index < aNameCount; ++index) {
    2264               0 :         if (!aNames[index]) {
    2265               0 :             aIdentifiers[index] = 0;
    2266               0 :             continue;
    2267                 :         }
    2268               0 :         nsDependentCString name(aNames[index]);
    2269               0 :         PluginIdentifierChildString* ident = self->mStringIdentifiers.Get(name);
    2270               0 :         if (!ident) {
    2271               0 :             nsCString nameCopy(name);
    2272                 : 
    2273               0 :             ident = new PluginIdentifierChildString(nameCopy);
    2274               0 :             self->SendPPluginIdentifierConstructor(ident, nameCopy, -1, false);
    2275                 :         }
    2276               0 :         ident->MakePermanent();
    2277               0 :         aIdentifiers[index] = ident;
    2278                 :     }
    2279               0 : }
    2280                 : 
    2281                 : bool NP_CALLBACK
    2282               0 : PluginModuleChild::NPN_IdentifierIsString(NPIdentifier aIdentifier)
    2283                 : {
    2284               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    2285                 : 
    2286                 :     PluginIdentifierChild* ident =
    2287               0 :         static_cast<PluginIdentifierChild*>(aIdentifier);
    2288               0 :     return ident->IsString();
    2289                 : }
    2290                 : 
    2291                 : NPIdentifier NP_CALLBACK
    2292               0 : PluginModuleChild::NPN_GetIntIdentifier(int32_t aIntId)
    2293                 : {
    2294               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    2295               0 :     AssertPluginThread();
    2296                 : 
    2297               0 :     PluginModuleChild* self = PluginModuleChild::current();
    2298                 : 
    2299               0 :     PluginIdentifierChildInt* ident = self->mIntIdentifiers.Get(aIntId);
    2300               0 :     if (!ident) {
    2301               0 :         nsCString voidString;
    2302               0 :         voidString.SetIsVoid(true);
    2303                 : 
    2304               0 :         ident = new PluginIdentifierChildInt(aIntId);
    2305               0 :         self->SendPPluginIdentifierConstructor(ident, voidString, aIntId, false);
    2306                 :     }
    2307               0 :     ident->MakePermanent();
    2308               0 :     return ident;
    2309                 : }
    2310                 : 
    2311                 : NPUTF8* NP_CALLBACK
    2312               0 : PluginModuleChild::NPN_UTF8FromIdentifier(NPIdentifier aIdentifier)
    2313                 : {
    2314               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    2315                 : 
    2316               0 :     if (static_cast<PluginIdentifierChild*>(aIdentifier)->IsString()) {
    2317               0 :       return static_cast<PluginIdentifierChildString*>(aIdentifier)->ToString();
    2318                 :     }
    2319               0 :     return nsnull;
    2320                 : }
    2321                 : 
    2322                 : int32_t NP_CALLBACK
    2323               0 : PluginModuleChild::NPN_IntFromIdentifier(NPIdentifier aIdentifier)
    2324                 : {
    2325               0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    2326                 : 
    2327               0 :     if (!static_cast<PluginIdentifierChild*>(aIdentifier)->IsString()) {
    2328               0 :       return static_cast<PluginIdentifierChildInt*>(aIdentifier)->ToInt();
    2329                 :     }
    2330               0 :     return PR_INT32_MIN;
    2331                 : }
    2332                 : 
    2333                 : #ifdef OS_WIN
    2334                 : void
    2335                 : PluginModuleChild::EnteredCall()
    2336                 : {
    2337                 :     mIncallPumpingStack.AppendElement();
    2338                 : }
    2339                 : 
    2340                 : void
    2341                 : PluginModuleChild::ExitedCall()
    2342                 : {
    2343                 :     NS_ASSERTION(mIncallPumpingStack.Length(), "mismatched entered/exited");
    2344                 :     PRUint32 len = mIncallPumpingStack.Length();
    2345                 :     const IncallFrame& f = mIncallPumpingStack[len - 1];
    2346                 :     if (f._spinning)
    2347                 :         MessageLoop::current()->SetNestableTasksAllowed(f._savedNestableTasksAllowed);
    2348                 : 
    2349                 :     mIncallPumpingStack.TruncateLength(len - 1);
    2350                 : }
    2351                 : 
    2352                 : LRESULT CALLBACK
    2353                 : PluginModuleChild::CallWindowProcHook(int nCode, WPARAM wParam, LPARAM lParam)
    2354                 : {
    2355                 :     // Trap and reply to anything we recognize as the source of a
    2356                 :     // potential send message deadlock.
    2357                 :     if (nCode >= 0 &&
    2358                 :         (InSendMessageEx(NULL)&(ISMEX_REPLIED|ISMEX_SEND)) == ISMEX_SEND) {
    2359                 :         CWPSTRUCT* pCwp = reinterpret_cast<CWPSTRUCT*>(lParam);
    2360                 :         if (pCwp->message == WM_KILLFOCUS) {
    2361                 :             // Fix for flash fullscreen window loosing focus. On single
    2362                 :             // core systems, sync killfocus events need to be handled
    2363                 :             // after the flash fullscreen window procedure processes this
    2364                 :             // message, otherwise fullscreen focus will not work correctly.
    2365                 :             PRUnichar szClass[26];
    2366                 :             if (GetClassNameW(pCwp->hwnd, szClass,
    2367                 :                               sizeof(szClass)/sizeof(PRUnichar)) &&
    2368                 :                 !wcscmp(szClass, kFlashFullscreenClass)) {
    2369                 :                 gDelayFlashFocusReplyUntilEval = true;
    2370                 :             }
    2371                 :         }
    2372                 :     }
    2373                 : 
    2374                 :     return CallNextHookEx(NULL, nCode, wParam, lParam);
    2375                 : }
    2376                 : 
    2377                 : LRESULT CALLBACK
    2378                 : PluginModuleChild::NestedInputEventHook(int nCode, WPARAM wParam, LPARAM lParam)
    2379                 : {
    2380                 :     PluginModuleChild* self = current();
    2381                 :     PRUint32 len = self->mIncallPumpingStack.Length();
    2382                 :     if (nCode >= 0 && len && !self->mIncallPumpingStack[len - 1]._spinning) {
    2383                 :         MessageLoop* loop = MessageLoop::current();
    2384                 :         self->SendProcessNativeEventsInRPCCall();
    2385                 :         IncallFrame& f = self->mIncallPumpingStack[len - 1];
    2386                 :         f._spinning = true;
    2387                 :         f._savedNestableTasksAllowed = loop->NestableTasksAllowed();
    2388                 :         loop->SetNestableTasksAllowed(true);
    2389                 :         loop->set_os_modal_loop(true);
    2390                 :     }
    2391                 : 
    2392                 :     return CallNextHookEx(NULL, nCode, wParam, lParam);
    2393                 : }
    2394                 : 
    2395                 : void
    2396                 : PluginModuleChild::SetEventHooks()
    2397                 : {
    2398                 :     NS_ASSERTION(!mNestedEventHook,
    2399                 :         "mNestedEventHook already setup in call to SetNestedInputEventHook?");
    2400                 :     NS_ASSERTION(!mGlobalCallWndProcHook,
    2401                 :         "mGlobalCallWndProcHook already setup in call to CallWindowProcHook?");
    2402                 : 
    2403                 :     PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
    2404                 : 
    2405                 :     // WH_MSGFILTER event hook for detecting modal loops in the child.
    2406                 :     mNestedEventHook = SetWindowsHookEx(WH_MSGFILTER,
    2407                 :                                         NestedInputEventHook,
    2408                 :                                         NULL,
    2409                 :                                         GetCurrentThreadId());
    2410                 : 
    2411                 :     // WH_CALLWNDPROC event hook for trapping sync messages sent from
    2412                 :     // parent that can cause deadlocks.
    2413                 :     mGlobalCallWndProcHook = SetWindowsHookEx(WH_CALLWNDPROC,
    2414                 :                                               CallWindowProcHook,
    2415                 :                                               NULL,
    2416                 :                                               GetCurrentThreadId());
    2417                 : }
    2418                 : 
    2419                 : void
    2420                 : PluginModuleChild::ResetEventHooks()
    2421                 : {
    2422                 :     PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
    2423                 :     if (mNestedEventHook)
    2424                 :         UnhookWindowsHookEx(mNestedEventHook);
    2425                 :     mNestedEventHook = NULL;
    2426                 :     if (mGlobalCallWndProcHook)
    2427                 :         UnhookWindowsHookEx(mGlobalCallWndProcHook);
    2428                 :     mGlobalCallWndProcHook = NULL;
    2429                 : }
    2430                 : #endif
    2431                 : 
    2432                 : bool
    2433               0 : PluginModuleChild::RecvProcessNativeEventsInRPCCall()
    2434                 : {
    2435               0 :     PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
    2436                 : #if defined(OS_WIN)
    2437                 :     ProcessNativeEventsInRPCCall();
    2438                 :     return true;
    2439                 : #else
    2440                 :     NS_RUNTIMEABORT(
    2441               0 :         "PluginModuleChild::RecvProcessNativeEventsInRPCCall not implemented!");
    2442               0 :     return false;
    2443                 : #endif
    2444                 : }
    2445                 : 
    2446                 : #ifdef MOZ_WIDGET_COCOA
    2447                 : void
    2448                 : PluginModuleChild::ProcessNativeEvents() {
    2449                 :     CallProcessSomeEvents();    
    2450                 : }
    2451                 : #endif

Generated by: LCOV version 1.7