LCOV - code coverage report
Current view: top level - dom/plugins/ipc - PluginModuleChild.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 715 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 100 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /* vim: set sw=4 ts=4 et : */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "mozilla/plugins/PluginModuleChild.h"
       8             : 
       9             : /* This must occur *after* plugins/PluginModuleChild.h to avoid typedefs conflicts. */
      10             : #include "mozilla/ArrayUtils.h"
      11             : 
      12             : #include "mozilla/ipc/MessageChannel.h"
      13             : 
      14             : #ifdef MOZ_WIDGET_GTK
      15             : #include <gtk/gtk.h>
      16             : #endif
      17             : 
      18             : #include "nsIFile.h"
      19             : 
      20             : #include "pratom.h"
      21             : #include "nsDebug.h"
      22             : #include "nsCOMPtr.h"
      23             : #include "nsPluginsDir.h"
      24             : #include "nsXULAppAPI.h"
      25             : 
      26             : #ifdef MOZ_X11
      27             : # include "nsX11ErrorHandler.h"
      28             : # include "mozilla/X11Util.h"
      29             : #endif
      30             : #include "mozilla/ipc/ProcessChild.h"
      31             : #include "mozilla/plugins/PluginInstanceChild.h"
      32             : #include "mozilla/plugins/StreamNotifyChild.h"
      33             : #include "mozilla/plugins/BrowserStreamChild.h"
      34             : #include "mozilla/Sprintf.h"
      35             : #include "mozilla/Unused.h"
      36             : 
      37             : #include "nsNPAPIPlugin.h"
      38             : 
      39             : #ifdef XP_WIN
      40             : #include "nsWindowsDllInterceptor.h"
      41             : #include "mozilla/widget/AudioSession.h"
      42             : #include <knownfolders.h>
      43             : #include <shlobj.h>
      44             : #endif
      45             : 
      46             : #ifdef MOZ_WIDGET_COCOA
      47             : #include "PluginInterposeOSX.h"
      48             : #include "PluginUtilsOSX.h"
      49             : #endif
      50             : 
      51             : #ifdef MOZ_CRASHREPORTER
      52             : #include "mozilla/ipc/CrashReporterClient.h"
      53             : #endif
      54             : 
      55             : #ifdef MOZ_GECKO_PROFILER
      56             : #include "ChildProfilerController.h"
      57             : #endif
      58             : 
      59             : using namespace mozilla;
      60             : using namespace mozilla::ipc;
      61             : using namespace mozilla::plugins;
      62             : using namespace mozilla::widget;
      63             : 
      64             : #if defined(XP_WIN)
      65             : const wchar_t * kFlashFullscreenClass = L"ShockwaveFlashFullScreen";
      66             : const wchar_t * kMozillaWindowClass = L"MozillaWindowClass";
      67             : #endif
      68             : 
      69             : namespace {
      70             : // see PluginModuleChild::GetChrome()
      71             : PluginModuleChild* gChromeInstance = nullptr;
      72             : } // namespace
      73             : 
      74             : #ifdef XP_WIN
      75             : // Hooking CreateFileW for protected-mode magic
      76             : static WindowsDllInterceptor sKernel32Intercept;
      77             : typedef HANDLE (WINAPI *CreateFileWPtr)(LPCWSTR fname, DWORD access,
      78             :                                         DWORD share,
      79             :                                         LPSECURITY_ATTRIBUTES security,
      80             :                                         DWORD creation, DWORD flags,
      81             :                                         HANDLE ftemplate);
      82             : static CreateFileWPtr sCreateFileWStub = nullptr;
      83             : typedef HANDLE (WINAPI *CreateFileAPtr)(LPCSTR fname, DWORD access,
      84             :                                         DWORD share,
      85             :                                         LPSECURITY_ATTRIBUTES security,
      86             :                                         DWORD creation, DWORD flags,
      87             :                                         HANDLE ftemplate);
      88             : static CreateFileAPtr sCreateFileAStub = nullptr;
      89             : 
      90             : // Used with fix for flash fullscreen window loosing focus.
      91             : static bool gDelayFlashFocusReplyUntilEval = false;
      92             : // Used to fix GetWindowInfo problems with internal flash settings dialogs
      93             : static WindowsDllInterceptor sUser32Intercept;
      94             : typedef BOOL (WINAPI *GetWindowInfoPtr)(HWND hwnd, PWINDOWINFO pwi);
      95             : static GetWindowInfoPtr sGetWindowInfoPtrStub = nullptr;
      96             : static HWND sBrowserHwnd = nullptr;
      97             : // sandbox process doesn't get current key states.  So we need get it on chrome.
      98             : typedef SHORT (WINAPI *GetKeyStatePtr)(int);
      99             : static GetKeyStatePtr sGetKeyStatePtrStub = nullptr;
     100             : 
     101             : static WindowsDllInterceptor sComDlg32Intercept;
     102             : 
     103             : // proxy GetSaveFileName/GetOpenFileName on chrome so that we can know which
     104             : // files the user has given permission to access
     105             : // We count on GetOpenFileNameA/GetSaveFileNameA calling
     106             : // GetOpenFileNameW/GetSaveFileNameW so we don't proxy them explicitly.
     107             : typedef BOOL (WINAPI *GetOpenFileNameWPtr)(LPOPENFILENAMEW lpofn);
     108             : static GetOpenFileNameWPtr sGetOpenFileNameWPtrStub = nullptr;
     109             : typedef BOOL (WINAPI *GetSaveFileNameWPtr)(LPOPENFILENAMEW lpofn);
     110             : static GetSaveFileNameWPtr sGetSaveFileNameWPtrStub = nullptr;
     111             : 
     112             : typedef BOOL (WINAPI *SetCursorPosPtr)(int x, int y);
     113             : static SetCursorPosPtr sSetCursorPosPtrStub = nullptr;
     114             : 
     115             : #endif
     116             : 
     117             : /* static */
     118             : bool
     119           0 : PluginModuleChild::CreateForContentProcess(Endpoint<PPluginModuleChild>&& aEndpoint)
     120             : {
     121           0 :     auto* child = new PluginModuleChild(false);
     122           0 :     return child->InitForContent(Move(aEndpoint));
     123             : }
     124             : 
     125           0 : PluginModuleChild::PluginModuleChild(bool aIsChrome)
     126             :   : mLibrary(0)
     127             :   , mPluginFilename("")
     128             :   , mQuirks(QUIRKS_NOT_INITIALIZED)
     129             :   , mIsChrome(aIsChrome)
     130             :   , mHasShutdown(false)
     131             :   , mShutdownFunc(0)
     132             :   , mInitializeFunc(0)
     133             : #if defined(OS_WIN) || defined(OS_MACOSX)
     134             :   , mGetEntryPointsFunc(0)
     135             : #elif defined(MOZ_WIDGET_GTK)
     136           0 :   , mNestedLoopTimerId(0)
     137             : #endif
     138             : #ifdef OS_WIN
     139             :   , mNestedEventHook(nullptr)
     140             :   , mGlobalCallWndProcHook(nullptr)
     141             :   , mAsyncRenderSupport(false)
     142             : #endif
     143             : {
     144           0 :     memset(&mFunctions, 0, sizeof(mFunctions));
     145           0 :     if (mIsChrome) {
     146           0 :         MOZ_ASSERT(!gChromeInstance);
     147           0 :         gChromeInstance = this;
     148             :     }
     149             : 
     150             : #ifdef XP_MACOSX
     151             :     if (aIsChrome) {
     152             :       mac_plugin_interposing::child::SetUpCocoaInterposing();
     153             :     }
     154             : #endif
     155           0 : }
     156             : 
     157           0 : PluginModuleChild::~PluginModuleChild()
     158             : {
     159           0 :     if (mIsChrome) {
     160           0 :         MOZ_ASSERT(gChromeInstance == this);
     161             : 
     162             :         // We don't unload the plugin library in case it uses atexit handlers or
     163             :         // other similar hooks.
     164             : 
     165           0 :         DeinitGraphics();
     166           0 :         PluginScriptableObjectChild::ClearIdentifiers();
     167             : 
     168           0 :         gChromeInstance = nullptr;
     169             :     }
     170           0 : }
     171             : 
     172             : // static
     173             : PluginModuleChild*
     174           0 : PluginModuleChild::GetChrome()
     175             : {
     176             :     // A special PluginModuleChild instance that talks to the chrome process
     177             :     // during startup and shutdown. Synchronous messages to or from this actor
     178             :     // should be avoided because they may lead to hangs.
     179           0 :     MOZ_ASSERT(gChromeInstance);
     180           0 :     return gChromeInstance;
     181             : }
     182             : 
     183             : void
     184           0 : PluginModuleChild::CommonInit()
     185             : {
     186           0 :     PLUGIN_LOG_DEBUG_METHOD;
     187             : 
     188             :     // Request Windows message deferral behavior on our channel. This
     189             :     // applies to the top level and all sub plugin protocols since they
     190             :     // all share the same channel.
     191             :     // Bug 1090573 - Don't do this for connections to content processes.
     192           0 :     GetIPCChannel()->SetChannelFlags(MessageChannel::REQUIRE_DEFERRED_MESSAGE_PROTECTION);
     193             : 
     194           0 :     memset((void*) &mFunctions, 0, sizeof(mFunctions));
     195           0 :     mFunctions.size = sizeof(mFunctions);
     196           0 :     mFunctions.version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
     197           0 : }
     198             : 
     199             : bool
     200           0 : PluginModuleChild::InitForContent(Endpoint<PPluginModuleChild>&& aEndpoint)
     201             : {
     202           0 :     CommonInit();
     203             : 
     204           0 :     if (!aEndpoint.Bind(this)) {
     205           0 :         return false;
     206             :     }
     207             : 
     208           0 :     mLibrary = GetChrome()->mLibrary;
     209           0 :     mFunctions = GetChrome()->mFunctions;
     210             : 
     211           0 :     return true;
     212             : }
     213             : 
     214             : mozilla::ipc::IPCResult
     215           0 : PluginModuleChild::RecvInitProfiler(Endpoint<mozilla::PProfilerChild>&& aEndpoint)
     216             : {
     217             : #ifdef MOZ_GECKO_PROFILER
     218           0 :     mProfilerController = ChildProfilerController::Create(Move(aEndpoint));
     219             : #endif
     220           0 :     return IPC_OK();
     221             : }
     222             : 
     223             : mozilla::ipc::IPCResult
     224           0 : PluginModuleChild::RecvDisableFlashProtectedMode()
     225             : {
     226           0 :     MOZ_ASSERT(mIsChrome);
     227             : #ifdef XP_WIN
     228             :     HookProtectedMode();
     229             : #else
     230           0 :     MOZ_ASSERT(false, "Should not be called");
     231             : #endif
     232             :     return IPC_OK();
     233             : }
     234             : 
     235             : bool
     236           0 : PluginModuleChild::InitForChrome(const std::string& aPluginFilename,
     237             :                                  base::ProcessId aParentPid,
     238             :                                  MessageLoop* aIOLoop,
     239             :                                  IPC::Channel* aChannel)
     240             : {
     241           0 :     NS_ASSERTION(aChannel, "need a channel");
     242             : 
     243           0 :     if (!InitGraphics())
     244           0 :         return false;
     245             : 
     246           0 :     mPluginFilename = aPluginFilename.c_str();
     247           0 :     nsCOMPtr<nsIFile> localFile;
     248           0 :     NS_NewLocalFile(NS_ConvertUTF8toUTF16(mPluginFilename),
     249             :                     true,
     250           0 :                     getter_AddRefs(localFile));
     251             : 
     252           0 :     if (!localFile)
     253           0 :         return false;
     254             : 
     255             :     bool exists;
     256           0 :     localFile->Exists(&exists);
     257           0 :     NS_ASSERTION(exists, "plugin file ain't there");
     258             : 
     259           0 :     nsPluginFile pluginFile(localFile);
     260             : 
     261           0 :     nsPluginInfo info = nsPluginInfo();
     262           0 :     if (NS_FAILED(pluginFile.GetPluginInfo(info, &mLibrary))) {
     263           0 :         return false;
     264             :     }
     265             : 
     266             : #if defined(XP_WIN)
     267             :     // XXX quirks isn't initialized yet
     268             :     mAsyncRenderSupport = info.fSupportsAsyncRender;
     269             : #endif
     270             : #if defined(MOZ_X11)
     271           0 :     NS_NAMED_LITERAL_CSTRING(flash10Head, "Shockwave Flash 10.");
     272           0 :     if (StringBeginsWith(nsDependentCString(info.fDescription), flash10Head)) {
     273           0 :         AddQuirk(QUIRK_FLASH_EXPOSE_COORD_TRANSLATION);
     274             :     }
     275             : #endif
     276             : #if defined(XP_MACOSX)
     277             :     const char* namePrefix = "Plugin Content";
     278             :     char nameBuffer[80];
     279             :     SprintfLiteral(nameBuffer, "%s (%s)", namePrefix, info.fName);
     280             :     mozilla::plugins::PluginUtilsOSX::SetProcessName(nameBuffer);
     281             : #endif
     282           0 :     pluginFile.FreePluginInfo(info);
     283             : #if defined(MOZ_X11) || defined(XP_MACOSX)
     284           0 :     if (!mLibrary)
     285             : #endif
     286             :     {
     287           0 :         nsresult rv = pluginFile.LoadPlugin(&mLibrary);
     288           0 :         if (NS_FAILED(rv))
     289           0 :             return false;
     290             :     }
     291           0 :     NS_ASSERTION(mLibrary, "couldn't open shared object");
     292             : 
     293           0 :     CommonInit();
     294             : 
     295           0 :     if (!Open(aChannel, aParentPid, aIOLoop)) {
     296           0 :         return false;
     297             :     }
     298             : 
     299           0 :     GetIPCChannel()->SetAbortOnError(true);
     300             : 
     301             :     // TODO: use PluginPRLibrary here
     302             : 
     303             : #if defined(OS_LINUX) || defined(OS_BSD) || defined(OS_SOLARIS)
     304           0 :     mShutdownFunc =
     305           0 :         (NP_PLUGINSHUTDOWN) PR_FindFunctionSymbol(mLibrary, "NP_Shutdown");
     306             : 
     307             :     // create the new plugin handler
     308             : 
     309           0 :     mInitializeFunc =
     310           0 :         (NP_PLUGINUNIXINIT) PR_FindFunctionSymbol(mLibrary, "NP_Initialize");
     311           0 :     NS_ASSERTION(mInitializeFunc, "couldn't find NP_Initialize()");
     312             : 
     313             : #elif defined(OS_WIN) || defined(OS_MACOSX)
     314             :     mShutdownFunc =
     315             :         (NP_PLUGINSHUTDOWN)PR_FindFunctionSymbol(mLibrary, "NP_Shutdown");
     316             : 
     317             :     mGetEntryPointsFunc =
     318             :         (NP_GETENTRYPOINTS)PR_FindSymbol(mLibrary, "NP_GetEntryPoints");
     319             :     NS_ENSURE_TRUE(mGetEntryPointsFunc, false);
     320             : 
     321             :     mInitializeFunc =
     322             :         (NP_PLUGININIT)PR_FindFunctionSymbol(mLibrary, "NP_Initialize");
     323             :     NS_ENSURE_TRUE(mInitializeFunc, false);
     324             : #else
     325             : 
     326             : #  error Please copy the initialization code from nsNPAPIPlugin.cpp
     327             : 
     328             : #endif
     329             : 
     330           0 :     return true;
     331             : }
     332             : 
     333             : #if defined(MOZ_WIDGET_GTK)
     334             : 
     335             : typedef void (*GObjectDisposeFn)(GObject*);
     336             : typedef gboolean (*GtkWidgetScrollEventFn)(GtkWidget*, GdkEventScroll*);
     337             : typedef void (*GtkPlugEmbeddedFn)(GtkPlug*);
     338             : 
     339             : static GObjectDisposeFn real_gtk_plug_dispose;
     340             : static GtkPlugEmbeddedFn real_gtk_plug_embedded;
     341             : 
     342             : static void
     343           0 : undo_bogus_unref(gpointer data, GObject* object, gboolean is_last_ref) {
     344           0 :     if (!is_last_ref) // recursion in g_object_ref
     345           0 :         return;
     346             : 
     347           0 :     g_object_ref(object);
     348             : }
     349             : 
     350             : static void
     351           0 : wrap_gtk_plug_dispose(GObject* object) {
     352             :     // Work around Flash Player bug described in bug 538914.
     353             :     //
     354             :     // This function is called during gtk_widget_destroy and/or before
     355             :     // the object's last reference is removed.  A reference to the
     356             :     // object is held during the call so the ref count should not drop
     357             :     // to zero.  However, Flash Player tries to destroy the GtkPlug
     358             :     // using g_object_unref instead of gtk_widget_destroy.  The
     359             :     // reference that Flash is removing actually belongs to the
     360             :     // GtkPlug.  During real_gtk_plug_dispose, the GtkPlug removes its
     361             :     // reference.
     362             :     //
     363             :     // A toggle ref is added to prevent premature deletion of the object
     364             :     // caused by Flash Player's extra unref, and to detect when there are
     365             :     // unexpectedly no other references.
     366           0 :     g_object_add_toggle_ref(object, undo_bogus_unref, nullptr);
     367           0 :     (*real_gtk_plug_dispose)(object);
     368           0 :     g_object_remove_toggle_ref(object, undo_bogus_unref, nullptr);
     369           0 : }
     370             : 
     371             : static gboolean
     372           0 : gtk_plug_scroll_event(GtkWidget *widget, GdkEventScroll *gdk_event)
     373             : {
     374           0 :     if (!gtk_widget_is_toplevel(widget)) // in same process as its GtkSocket
     375           0 :         return FALSE; // event not handled; propagate to GtkSocket
     376             : 
     377           0 :     GdkWindow* socket_window = gtk_plug_get_socket_window(GTK_PLUG(widget));
     378           0 :     if (!socket_window)
     379           0 :         return FALSE;
     380             : 
     381             :     // Propagate the event to the embedder.
     382           0 :     GdkScreen* screen = gdk_window_get_screen(socket_window);
     383           0 :     GdkWindow* plug_window = gtk_widget_get_window(widget);
     384           0 :     GdkWindow* event_window = gdk_event->window;
     385           0 :     gint x = gdk_event->x;
     386           0 :     gint y = gdk_event->y;
     387             :     unsigned int button;
     388           0 :     unsigned int button_mask = 0;
     389             :     XEvent xevent;
     390           0 :     Display* dpy = GDK_WINDOW_XDISPLAY(socket_window);
     391             : 
     392             :     /* Translate the event coordinates to the plug window,
     393             :      * which should be aligned with the socket window.
     394             :      */
     395           0 :     while (event_window != plug_window)
     396             :     {
     397             :         gint dx, dy;
     398             : 
     399           0 :         gdk_window_get_position(event_window, &dx, &dy);
     400           0 :         x += dx;
     401           0 :         y += dy;
     402             : 
     403           0 :         event_window = gdk_window_get_parent(event_window);
     404           0 :         if (!event_window)
     405           0 :             return FALSE;
     406             :     }
     407             : 
     408           0 :     switch (gdk_event->direction) {
     409             :     case GDK_SCROLL_UP:
     410           0 :         button = 4;
     411           0 :         button_mask = Button4Mask;
     412           0 :         break;
     413             :     case GDK_SCROLL_DOWN:
     414           0 :         button = 5;
     415           0 :         button_mask = Button5Mask;
     416           0 :         break;
     417             :     case GDK_SCROLL_LEFT:
     418           0 :         button = 6;
     419           0 :         break;
     420             :     case GDK_SCROLL_RIGHT:
     421           0 :         button = 7;
     422           0 :         break;
     423             :     default:
     424           0 :         return FALSE; // unknown GdkScrollDirection
     425             :     }
     426             : 
     427           0 :     memset(&xevent, 0, sizeof(xevent));
     428           0 :     xevent.xbutton.type = ButtonPress;
     429           0 :     xevent.xbutton.window = gdk_x11_window_get_xid(socket_window);
     430           0 :     xevent.xbutton.root = gdk_x11_window_get_xid(gdk_screen_get_root_window(screen));
     431           0 :     xevent.xbutton.subwindow = gdk_x11_window_get_xid(plug_window);
     432           0 :     xevent.xbutton.time = gdk_event->time;
     433           0 :     xevent.xbutton.x = x;
     434           0 :     xevent.xbutton.y = y;
     435           0 :     xevent.xbutton.x_root = gdk_event->x_root;
     436           0 :     xevent.xbutton.y_root = gdk_event->y_root;
     437           0 :     xevent.xbutton.state = gdk_event->state;
     438           0 :     xevent.xbutton.button = button;
     439           0 :     xevent.xbutton.same_screen = True;
     440             : 
     441           0 :     gdk_error_trap_push();
     442             : 
     443           0 :     XSendEvent(dpy, xevent.xbutton.window,
     444           0 :                True, ButtonPressMask, &xevent);
     445             : 
     446           0 :     xevent.xbutton.type = ButtonRelease;
     447           0 :     xevent.xbutton.state |= button_mask;
     448           0 :     XSendEvent(dpy, xevent.xbutton.window,
     449           0 :                True, ButtonReleaseMask, &xevent);
     450             : 
     451           0 :     gdk_display_sync(gdk_screen_get_display(screen));
     452           0 :     gdk_error_trap_pop();
     453             : 
     454           0 :     return TRUE; // event handled
     455             : }
     456             : 
     457             : static void
     458           0 : wrap_gtk_plug_embedded(GtkPlug* plug) {
     459           0 :     GdkWindow* socket_window = gtk_plug_get_socket_window(plug);
     460           0 :     if (socket_window) {
     461           0 :         if (gtk_check_version(2,18,7) != nullptr // older
     462           0 :             && g_object_get_data(G_OBJECT(socket_window),
     463             :                                  "moz-existed-before-set-window")) {
     464             :             // Add missing reference for
     465             :             // https://bugzilla.gnome.org/show_bug.cgi?id=607061
     466           0 :             g_object_ref(socket_window);
     467             :         }
     468             : 
     469             :         // Ensure the window exists to make this GtkPlug behave like an
     470             :         // in-process GtkPlug for Flash Player.  (Bugs 561308 and 539138).
     471           0 :         gtk_widget_realize(GTK_WIDGET(plug));
     472             :     }
     473             : 
     474           0 :     if (*real_gtk_plug_embedded) {
     475           0 :         (*real_gtk_plug_embedded)(plug);
     476             :     }
     477           0 : }
     478             : 
     479             : //
     480             : // The next four constants are knobs that can be tuned.  They trade
     481             : // off potential UI lag from delayed event processing with CPU time.
     482             : //
     483             : static const gint kNestedLoopDetectorPriority = G_PRIORITY_HIGH_IDLE;
     484             : // 90ms so that we can hopefully break livelocks before the user
     485             : // notices UI lag (100ms)
     486             : static const guint kNestedLoopDetectorIntervalMs = 90;
     487             : 
     488             : static const gint kBrowserEventPriority = G_PRIORITY_HIGH_IDLE;
     489             : static const guint kBrowserEventIntervalMs = 10;
     490             : 
     491             : // static
     492             : gboolean
     493           0 : PluginModuleChild::DetectNestedEventLoop(gpointer data)
     494             : {
     495           0 :     PluginModuleChild* pmc = static_cast<PluginModuleChild*>(data);
     496             : 
     497           0 :     MOZ_ASSERT(0 != pmc->mNestedLoopTimerId,
     498             :                "callback after descheduling");
     499           0 :     MOZ_ASSERT(pmc->mTopLoopDepth < g_main_depth(),
     500             :                "not canceled before returning to main event loop!");
     501             : 
     502           0 :     PLUGIN_LOG_DEBUG(("Detected nested glib event loop"));
     503             : 
     504             :     // just detected a nested loop; start a timer that will
     505             :     // periodically rpc-call back into the browser and process some
     506             :     // events
     507           0 :     pmc->mNestedLoopTimerId =
     508           0 :         g_timeout_add_full(kBrowserEventPriority,
     509             :                            kBrowserEventIntervalMs,
     510             :                            PluginModuleChild::ProcessBrowserEvents,
     511             :                            data,
     512             :                            nullptr);
     513             :     // cancel the nested-loop detection timer
     514           0 :     return FALSE;
     515             : }
     516             : 
     517             : // static
     518             : gboolean
     519           0 : PluginModuleChild::ProcessBrowserEvents(gpointer data)
     520             : {
     521           0 :     PluginModuleChild* pmc = static_cast<PluginModuleChild*>(data);
     522             : 
     523           0 :     MOZ_ASSERT(pmc->mTopLoopDepth < g_main_depth(),
     524             :                "not canceled before returning to main event loop!");
     525             : 
     526           0 :     pmc->CallProcessSomeEvents();
     527             : 
     528           0 :     return TRUE;
     529             : }
     530             : 
     531             : void
     532           0 : PluginModuleChild::EnteredCxxStack()
     533             : {
     534           0 :     MOZ_ASSERT(0 == mNestedLoopTimerId,
     535             :                "previous timer not descheduled");
     536             : 
     537           0 :     mNestedLoopTimerId =
     538           0 :         g_timeout_add_full(kNestedLoopDetectorPriority,
     539             :                            kNestedLoopDetectorIntervalMs,
     540             :                            PluginModuleChild::DetectNestedEventLoop,
     541             :                            this,
     542             :                            nullptr);
     543             : 
     544             : #ifdef DEBUG
     545           0 :     mTopLoopDepth = g_main_depth();
     546             : #endif
     547           0 : }
     548             : 
     549             : void
     550           0 : PluginModuleChild::ExitedCxxStack()
     551             : {
     552           0 :     MOZ_ASSERT(0 < mNestedLoopTimerId,
     553             :                "nested loop timeout not scheduled");
     554             : 
     555           0 :     g_source_remove(mNestedLoopTimerId);
     556           0 :     mNestedLoopTimerId = 0;
     557           0 : }
     558             : 
     559             : #endif
     560             : 
     561             : mozilla::ipc::IPCResult
     562           0 : PluginModuleChild::RecvSetParentHangTimeout(const uint32_t& aSeconds)
     563             : {
     564             : #ifdef XP_WIN
     565             :     SetReplyTimeoutMs(((aSeconds > 0) ? (1000 * aSeconds) : 0));
     566             : #endif
     567           0 :     return IPC_OK();
     568             : }
     569             : 
     570             : bool
     571           0 : PluginModuleChild::ShouldContinueFromReplyTimeout()
     572             : {
     573             : #ifdef XP_WIN
     574             :     MOZ_CRASH("terminating child process");
     575             : #endif
     576           0 :     return true;
     577             : }
     578             : 
     579             : bool
     580           0 : PluginModuleChild::InitGraphics()
     581             : {
     582             : #if defined(MOZ_WIDGET_GTK)
     583             :     // Work around plugins that don't interact well with GDK
     584             :     // client-side windows.
     585           0 :     PR_SetEnv("GDK_NATIVE_WINDOWS=1");
     586             : 
     587           0 :     gtk_init(0, 0);
     588             : 
     589             :     // GtkPlug is a static class so will leak anyway but this ref makes sure.
     590           0 :     gpointer gtk_plug_class = g_type_class_ref(GTK_TYPE_PLUG);
     591             : 
     592             :     // The dispose method is a good place to hook into the destruction process
     593             :     // because the reference count should be 1 the last time dispose is
     594             :     // called.  (Toggle references wouldn't detect if the reference count
     595             :     // might be higher.)
     596           0 :     GObjectDisposeFn* dispose = &G_OBJECT_CLASS(gtk_plug_class)->dispose;
     597           0 :     MOZ_ASSERT(*dispose != wrap_gtk_plug_dispose,
     598             :                "InitGraphics called twice");
     599           0 :     real_gtk_plug_dispose = *dispose;
     600           0 :     *dispose = wrap_gtk_plug_dispose;
     601             : 
     602             :     // If we ever stop setting GDK_NATIVE_WINDOWS, we'll also need to
     603             :     // gtk_widget_add_events GDK_SCROLL_MASK or GDK client-side windows will
     604             :     // not tell us about the scroll events that it intercepts.  With native
     605             :     // windows, this is called when GDK intercepts the events; if GDK doesn't
     606             :     // intercept the events, then the X server will instead send them directly
     607             :     // to an ancestor (embedder) window.
     608             :     GtkWidgetScrollEventFn* scroll_event =
     609           0 :         &GTK_WIDGET_CLASS(gtk_plug_class)->scroll_event;
     610           0 :     if (!*scroll_event) {
     611           0 :         *scroll_event = gtk_plug_scroll_event;
     612             :     }
     613             : 
     614           0 :     GtkPlugEmbeddedFn* embedded = &GTK_PLUG_CLASS(gtk_plug_class)->embedded;
     615           0 :     real_gtk_plug_embedded = *embedded;
     616           0 :     *embedded = wrap_gtk_plug_embedded;
     617             : 
     618             : #else
     619             :     // may not be necessary on all platforms
     620             : #endif
     621             : #ifdef MOZ_X11
     622             :     // Do this after initializing GDK, or GDK will install its own handler.
     623           0 :     InstallX11ErrorHandler();
     624             : #endif
     625           0 :     return true;
     626             : }
     627             : 
     628             : void
     629           0 : PluginModuleChild::DeinitGraphics()
     630             : {
     631             : #if defined(MOZ_X11) && defined(NS_FREE_PERMANENT_DATA)
     632             :     // We free some data off of XDisplay close hooks, ensure they're
     633             :     // run.  Closing the display is pretty scary, so we only do it to
     634             :     // silence leak checkers.
     635           0 :     XCloseDisplay(DefaultXDisplay());
     636             : #endif
     637           0 : }
     638             : 
     639             : NPError
     640           0 : PluginModuleChild::NP_Shutdown()
     641             : {
     642           0 :     AssertPluginThread();
     643           0 :     MOZ_ASSERT(mIsChrome);
     644             : 
     645           0 :     if (mHasShutdown) {
     646           0 :         return NPERR_NO_ERROR;
     647             :     }
     648             : 
     649             : #if defined XP_WIN
     650             :     mozilla::widget::StopAudioSession();
     651             : #endif
     652             : 
     653             :     // the PluginModuleParent shuts down this process after this interrupt
     654             :     // call pops off its stack
     655             : 
     656           0 :     NPError rv = mShutdownFunc ? mShutdownFunc() : NPERR_NO_ERROR;
     657             : 
     658             :     // weakly guard against re-entry after NP_Shutdown
     659           0 :     memset(&mFunctions, 0, sizeof(mFunctions));
     660             : 
     661             : #ifdef OS_WIN
     662             :     ResetEventHooks();
     663             : #endif
     664             : 
     665           0 :     GetIPCChannel()->SetAbortOnError(false);
     666             : 
     667           0 :     mHasShutdown = true;
     668             : 
     669           0 :     return rv;
     670             : }
     671             : 
     672             : mozilla::ipc::IPCResult
     673           0 : PluginModuleChild::AnswerNP_Shutdown(NPError *rv)
     674             : {
     675           0 :     *rv = NP_Shutdown();
     676           0 :     return IPC_OK();
     677             : }
     678             : 
     679             : mozilla::ipc::IPCResult
     680           0 : PluginModuleChild::AnswerOptionalFunctionsSupported(bool *aURLRedirectNotify,
     681             :                                                     bool *aClearSiteData,
     682             :                                                     bool *aGetSitesWithData)
     683             : {
     684           0 :     *aURLRedirectNotify = !!mFunctions.urlredirectnotify;
     685           0 :     *aClearSiteData = !!mFunctions.clearsitedata;
     686           0 :     *aGetSitesWithData = !!mFunctions.getsiteswithdata;
     687           0 :     return IPC_OK();
     688             : }
     689             : 
     690             : mozilla::ipc::IPCResult
     691           0 : PluginModuleChild::RecvNPP_ClearSiteData(const nsCString& aSite,
     692             :                                            const uint64_t& aFlags,
     693             :                                            const uint64_t& aMaxAge,
     694             :                                            const uint64_t& aCallbackId)
     695             : {
     696             :     NPError result =
     697           0 :         mFunctions.clearsitedata(NullableStringGet(aSite), aFlags, aMaxAge);
     698           0 :     SendReturnClearSiteData(result, aCallbackId);
     699           0 :     return IPC_OK();
     700             : }
     701             : 
     702             : mozilla::ipc::IPCResult
     703           0 : PluginModuleChild::RecvNPP_GetSitesWithData(const uint64_t& aCallbackId)
     704             : {
     705           0 :     char** result = mFunctions.getsiteswithdata();
     706           0 :     InfallibleTArray<nsCString> array;
     707           0 :     if (!result) {
     708           0 :         SendReturnSitesWithData(array, aCallbackId);
     709           0 :         return IPC_OK();
     710             :     }
     711           0 :     char** iterator = result;
     712           0 :     while (*iterator) {
     713           0 :         array.AppendElement(*iterator);
     714           0 :         free(*iterator);
     715           0 :         ++iterator;
     716             :     }
     717           0 :     SendReturnSitesWithData(array, aCallbackId);
     718           0 :     free(result);
     719           0 :     return IPC_OK();
     720             : }
     721             : 
     722             : mozilla::ipc::IPCResult
     723           0 : PluginModuleChild::RecvSetAudioSessionData(const nsID& aId,
     724             :                                            const nsString& aDisplayName,
     725             :                                            const nsString& aIconPath)
     726             : {
     727             : #if !defined XP_WIN
     728           0 :     NS_RUNTIMEABORT("Not Reached!");
     729           0 :     return IPC_FAIL_NO_REASON(this);
     730             : #else
     731             :     nsresult rv = mozilla::widget::RecvAudioSessionData(aId, aDisplayName, aIconPath);
     732             :     NS_ENSURE_SUCCESS(rv, IPC_OK()); // Bail early if this fails
     733             : 
     734             :     // Ignore failures here; we can't really do anything about them
     735             :     mozilla::widget::StartAudioSession();
     736             :     return IPC_OK();
     737             : #endif
     738             : }
     739             : 
     740             : mozilla::ipc::IPCResult
     741           0 : PluginModuleChild::RecvInitPluginModuleChild(Endpoint<PPluginModuleChild>&& aEndpoint)
     742             : {
     743           0 :     if (!CreateForContentProcess(Move(aEndpoint))) {
     744           0 :         return IPC_FAIL(this, "CreateForContentProcess failed");
     745             :     }
     746           0 :     return IPC_OK();
     747             : }
     748             : 
     749             : 
     750             : mozilla::ipc::IPCResult
     751           0 : PluginModuleChild::AnswerInitCrashReporter(Shmem&& aShmem, mozilla::dom::NativeThreadId* aOutId)
     752             : {
     753             : #ifdef MOZ_CRASHREPORTER
     754           0 :     CrashReporterClient::InitSingletonWithShmem(aShmem);
     755           0 :     *aOutId = CrashReporter::CurrentThreadId();
     756             : #endif
     757           0 :     return IPC_OK();
     758             : }
     759             : 
     760             : void
     761           0 : PluginModuleChild::ActorDestroy(ActorDestroyReason why)
     762             : {
     763             : #ifdef MOZ_GECKO_PROFILER
     764           0 :     if (mProfilerController) {
     765           0 :         mProfilerController->Shutdown();
     766           0 :         mProfilerController = nullptr;
     767             :     }
     768             : #endif
     769             : 
     770           0 :     if (!mIsChrome) {
     771           0 :         PluginModuleChild* chromeInstance = PluginModuleChild::GetChrome();
     772           0 :         if (chromeInstance) {
     773           0 :             chromeInstance->SendNotifyContentModuleDestroyed();
     774             :         }
     775             : 
     776             :         // Destroy ourselves once we finish other teardown activities.
     777             :         RefPtr<DeleteTask<PluginModuleChild>> task =
     778           0 :             new DeleteTask<PluginModuleChild>(this);
     779           0 :         MessageLoop::current()->PostTask(task.forget());
     780           0 :         return;
     781             :     }
     782             : 
     783           0 :     if (AbnormalShutdown == why) {
     784           0 :         NS_WARNING("shutting down early because of crash!");
     785           0 :         ProcessChild::QuickExit();
     786             :     }
     787             : 
     788           0 :     if (!mHasShutdown) {
     789           0 :         MOZ_ASSERT(gChromeInstance == this);
     790           0 :         NP_Shutdown();
     791             :     }
     792             : 
     793             :     // doesn't matter why we're being destroyed; it's up to us to
     794             :     // initiate (clean) shutdown
     795             : #ifdef MOZ_CRASHREPORTER
     796           0 :     CrashReporterClient::DestroySingleton();
     797             : #endif
     798           0 :     XRE_ShutdownChildProcess();
     799             : }
     800             : 
     801             : void
     802           0 : PluginModuleChild::CleanUp()
     803             : {
     804           0 : }
     805             : 
     806             : const char*
     807           0 : PluginModuleChild::GetUserAgent()
     808             : {
     809           0 :     return NullableStringGet(Settings().userAgent());
     810             : }
     811             : 
     812             : //-----------------------------------------------------------------------------
     813             : // FIXME/cjones: just getting this out of the way for the moment ...
     814             : 
     815             : namespace mozilla {
     816             : namespace plugins {
     817             : namespace child {
     818             : 
     819             : static NPError
     820             : _requestread(NPStream *pstream, NPByteRange *rangeList);
     821             : 
     822             : static NPError
     823             : _geturlnotify(NPP aNPP, const char* relativeURL, const char* target,
     824             :               void* notifyData);
     825             : 
     826             : static NPError
     827             : _getvalue(NPP aNPP, NPNVariable variable, void *r_value);
     828             : 
     829             : static NPError
     830             : _setvalue(NPP aNPP, NPPVariable variable, void *r_value);
     831             : 
     832             : static NPError
     833             : _geturl(NPP aNPP, const char* relativeURL, const char* target);
     834             : 
     835             : static NPError
     836             : _posturlnotify(NPP aNPP, const char* relativeURL, const char *target,
     837             :                uint32_t len, const char *buf, NPBool file, void* notifyData);
     838             : 
     839             : static NPError
     840             : _posturl(NPP aNPP, const char* relativeURL, const char *target, uint32_t len,
     841             :          const char *buf, NPBool file);
     842             : 
     843             : static void
     844             : _status(NPP aNPP, const char *message);
     845             : 
     846             : static void
     847             : _memfree (void *ptr);
     848             : 
     849             : static uint32_t
     850             : _memflush(uint32_t size);
     851             : 
     852             : static void
     853             : _reloadplugins(NPBool reloadPages);
     854             : 
     855             : static void
     856             : _invalidaterect(NPP aNPP, NPRect *invalidRect);
     857             : 
     858             : static void
     859             : _invalidateregion(NPP aNPP, NPRegion invalidRegion);
     860             : 
     861             : static void
     862             : _forceredraw(NPP aNPP);
     863             : 
     864             : static const char*
     865             : _useragent(NPP aNPP);
     866             : 
     867             : static void*
     868             : _memalloc (uint32_t size);
     869             : 
     870             : // Deprecated entry points for the old Java plugin.
     871             : static void* /* OJI type: JRIEnv* */
     872             : _getjavaenv(void);
     873             : 
     874             : // Deprecated entry points for the old Java plugin.
     875             : static void* /* OJI type: jref */
     876             : _getjavapeer(NPP aNPP);
     877             : 
     878             : static bool
     879             : _invoke(NPP aNPP, NPObject* npobj, NPIdentifier method, const NPVariant *args,
     880             :         uint32_t argCount, NPVariant *result);
     881             : 
     882             : static bool
     883             : _invokedefault(NPP aNPP, NPObject* npobj, const NPVariant *args,
     884             :                uint32_t argCount, NPVariant *result);
     885             : 
     886             : static bool
     887             : _evaluate(NPP aNPP, NPObject* npobj, NPString *script, NPVariant *result);
     888             : 
     889             : static bool
     890             : _getproperty(NPP aNPP, NPObject* npobj, NPIdentifier property,
     891             :              NPVariant *result);
     892             : 
     893             : static bool
     894             : _setproperty(NPP aNPP, NPObject* npobj, NPIdentifier property,
     895             :              const NPVariant *value);
     896             : 
     897             : static bool
     898             : _removeproperty(NPP aNPP, NPObject* npobj, NPIdentifier property);
     899             : 
     900             : static bool
     901             : _hasproperty(NPP aNPP, NPObject* npobj, NPIdentifier propertyName);
     902             : 
     903             : static bool
     904             : _hasmethod(NPP aNPP, NPObject* npobj, NPIdentifier methodName);
     905             : 
     906             : static bool
     907             : _enumerate(NPP aNPP, NPObject *npobj, NPIdentifier **identifier,
     908             :            uint32_t *count);
     909             : 
     910             : static bool
     911             : _construct(NPP aNPP, NPObject* npobj, const NPVariant *args,
     912             :            uint32_t argCount, NPVariant *result);
     913             : 
     914             : static void
     915             : _releasevariantvalue(NPVariant *variant);
     916             : 
     917             : static void
     918             : _setexception(NPObject* npobj, const NPUTF8 *message);
     919             : 
     920             : static void
     921             : _pushpopupsenabledstate(NPP aNPP, NPBool enabled);
     922             : 
     923             : static void
     924             : _poppopupsenabledstate(NPP aNPP);
     925             : 
     926             : static void
     927             : _pluginthreadasynccall(NPP instance, PluginThreadCallback func,
     928             :                        void *userData);
     929             : 
     930             : static NPError
     931             : _getvalueforurl(NPP npp, NPNURLVariable variable, const char *url,
     932             :                 char **value, uint32_t *len);
     933             : 
     934             : static NPError
     935             : _setvalueforurl(NPP npp, NPNURLVariable variable, const char *url,
     936             :                 const char *value, uint32_t len);
     937             : 
     938             : static uint32_t
     939             : _scheduletimer(NPP instance, uint32_t interval, NPBool repeat,
     940             :                void (*timerFunc)(NPP npp, uint32_t timerID));
     941             : 
     942             : static void
     943             : _unscheduletimer(NPP instance, uint32_t timerID);
     944             : 
     945             : static NPError
     946             : _popupcontextmenu(NPP instance, NPMenu* menu);
     947             : 
     948             : static NPBool
     949             : _convertpoint(NPP instance,
     950             :               double sourceX, double sourceY, NPCoordinateSpace sourceSpace,
     951             :               double *destX, double *destY, NPCoordinateSpace destSpace);
     952             : 
     953             : static void
     954             : _urlredirectresponse(NPP instance, void* notifyData, NPBool allow);
     955             : 
     956             : static NPError
     957             : _initasyncsurface(NPP instance, NPSize *size,
     958             :                   NPImageFormat format, void *initData,
     959             :                   NPAsyncSurface *surface);
     960             : 
     961             : static NPError
     962             : _finalizeasyncsurface(NPP instance, NPAsyncSurface *surface);
     963             : 
     964             : static void
     965             : _setcurrentasyncsurface(NPP instance, NPAsyncSurface *surface, NPRect *changed);
     966             : 
     967             : } /* namespace child */
     968             : } /* namespace plugins */
     969             : } /* namespace mozilla */
     970             : 
     971             : const NPNetscapeFuncs PluginModuleChild::sBrowserFuncs = {
     972             :     sizeof(sBrowserFuncs),
     973             :     (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR,
     974             :     mozilla::plugins::child::_geturl,
     975             :     mozilla::plugins::child::_posturl,
     976             :     mozilla::plugins::child::_requestread,
     977             :     nullptr,
     978             :     nullptr,
     979             :     nullptr,
     980             :     mozilla::plugins::child::_status,
     981             :     mozilla::plugins::child::_useragent,
     982             :     mozilla::plugins::child::_memalloc,
     983             :     mozilla::plugins::child::_memfree,
     984             :     mozilla::plugins::child::_memflush,
     985             :     mozilla::plugins::child::_reloadplugins,
     986             :     mozilla::plugins::child::_getjavaenv,
     987             :     mozilla::plugins::child::_getjavapeer,
     988             :     mozilla::plugins::child::_geturlnotify,
     989             :     mozilla::plugins::child::_posturlnotify,
     990             :     mozilla::plugins::child::_getvalue,
     991             :     mozilla::plugins::child::_setvalue,
     992             :     mozilla::plugins::child::_invalidaterect,
     993             :     mozilla::plugins::child::_invalidateregion,
     994             :     mozilla::plugins::child::_forceredraw,
     995             :     PluginModuleChild::NPN_GetStringIdentifier,
     996             :     PluginModuleChild::NPN_GetStringIdentifiers,
     997             :     PluginModuleChild::NPN_GetIntIdentifier,
     998             :     PluginModuleChild::NPN_IdentifierIsString,
     999             :     PluginModuleChild::NPN_UTF8FromIdentifier,
    1000             :     PluginModuleChild::NPN_IntFromIdentifier,
    1001             :     PluginModuleChild::NPN_CreateObject,
    1002             :     PluginModuleChild::NPN_RetainObject,
    1003             :     PluginModuleChild::NPN_ReleaseObject,
    1004             :     mozilla::plugins::child::_invoke,
    1005             :     mozilla::plugins::child::_invokedefault,
    1006             :     mozilla::plugins::child::_evaluate,
    1007             :     mozilla::plugins::child::_getproperty,
    1008             :     mozilla::plugins::child::_setproperty,
    1009             :     mozilla::plugins::child::_removeproperty,
    1010             :     mozilla::plugins::child::_hasproperty,
    1011             :     mozilla::plugins::child::_hasmethod,
    1012             :     mozilla::plugins::child::_releasevariantvalue,
    1013             :     mozilla::plugins::child::_setexception,
    1014             :     mozilla::plugins::child::_pushpopupsenabledstate,
    1015             :     mozilla::plugins::child::_poppopupsenabledstate,
    1016             :     mozilla::plugins::child::_enumerate,
    1017             :     mozilla::plugins::child::_pluginthreadasynccall,
    1018             :     mozilla::plugins::child::_construct,
    1019             :     mozilla::plugins::child::_getvalueforurl,
    1020             :     mozilla::plugins::child::_setvalueforurl,
    1021             :     nullptr, //NPN GetAuthenticationInfo, not supported
    1022             :     mozilla::plugins::child::_scheduletimer,
    1023             :     mozilla::plugins::child::_unscheduletimer,
    1024             :     mozilla::plugins::child::_popupcontextmenu,
    1025             :     mozilla::plugins::child::_convertpoint,
    1026             :     nullptr, // handleevent, unimplemented
    1027             :     nullptr, // unfocusinstance, unimplemented
    1028             :     mozilla::plugins::child::_urlredirectresponse,
    1029             :     mozilla::plugins::child::_initasyncsurface,
    1030             :     mozilla::plugins::child::_finalizeasyncsurface,
    1031             :     mozilla::plugins::child::_setcurrentasyncsurface,
    1032             : };
    1033             : 
    1034             : PluginInstanceChild*
    1035           0 : InstCast(NPP aNPP)
    1036             : {
    1037           0 :     MOZ_ASSERT(!!(aNPP->ndata), "nil instance");
    1038           0 :     return static_cast<PluginInstanceChild*>(aNPP->ndata);
    1039             : }
    1040             : 
    1041             : namespace mozilla {
    1042             : namespace plugins {
    1043             : namespace child {
    1044             : 
    1045             : NPError
    1046           0 : _requestread(NPStream* aStream,
    1047             :              NPByteRange* aRangeList)
    1048             : {
    1049           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1050           0 :     ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM);
    1051             : 
    1052             :     BrowserStreamChild* bs =
    1053           0 :         static_cast<BrowserStreamChild*>(static_cast<AStream*>(aStream->ndata));
    1054           0 :     bs->EnsureCorrectStream(aStream);
    1055           0 :     return bs->NPN_RequestRead(aRangeList);
    1056             : }
    1057             : 
    1058             : NPError
    1059           0 : _geturlnotify(NPP aNPP,
    1060             :               const char* aRelativeURL,
    1061             :               const char* aTarget,
    1062             :               void* aNotifyData)
    1063             : {
    1064           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1065           0 :     ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM);
    1066             : 
    1067           0 :     if (!aNPP) // nullptr check for nspluginwrapper (bug 561690)
    1068           0 :         return NPERR_INVALID_INSTANCE_ERROR;
    1069             : 
    1070           0 :     nsCString url = NullableString(aRelativeURL);
    1071           0 :     auto* sn = new StreamNotifyChild(url);
    1072             : 
    1073             :     NPError err;
    1074           0 :     InstCast(aNPP)->CallPStreamNotifyConstructor(
    1075           0 :         sn, url, NullableString(aTarget), false, nsCString(), false, &err);
    1076             : 
    1077           0 :     if (NPERR_NO_ERROR == err) {
    1078             :         // If NPN_PostURLNotify fails, the parent will immediately send us
    1079             :         // a PStreamNotifyDestructor, which should not call NPP_URLNotify.
    1080           0 :         sn->SetValid(aNotifyData);
    1081             :     }
    1082             : 
    1083           0 :     return err;
    1084             : }
    1085             : 
    1086             : NPError
    1087           0 : _getvalue(NPP aNPP,
    1088             :           NPNVariable aVariable,
    1089             :           void* aValue)
    1090             : {
    1091           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1092           0 :     ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM);
    1093             : 
    1094           0 :     switch (aVariable) {
    1095             :         // Copied from nsNPAPIPlugin.cpp
    1096             :         case NPNVToolkit:
    1097             : #if defined(MOZ_WIDGET_GTK)
    1098           0 :             *static_cast<NPNToolkitType*>(aValue) = NPNVGtk2;
    1099           0 :             return NPERR_NO_ERROR;
    1100             : #endif
    1101             :             return NPERR_GENERIC_ERROR;
    1102             : 
    1103             :         case NPNVjavascriptEnabledBool:
    1104           0 :             *(NPBool*)aValue = PluginModuleChild::GetChrome()->Settings().javascriptEnabled();
    1105           0 :             return NPERR_NO_ERROR;
    1106             :         case NPNVasdEnabledBool:
    1107           0 :             *(NPBool*)aValue = PluginModuleChild::GetChrome()->Settings().asdEnabled();
    1108           0 :             return NPERR_NO_ERROR;
    1109             :         case NPNVisOfflineBool:
    1110           0 :             *(NPBool*)aValue = PluginModuleChild::GetChrome()->Settings().isOffline();
    1111           0 :             return NPERR_NO_ERROR;
    1112             :         case NPNVSupportsXEmbedBool:
    1113             :             // We don't support windowed xembed any more. But we still deliver
    1114             :             // events based on X/GTK, not Xt, so we continue to return true
    1115             :             // (and Flash requires that we return true).
    1116           0 :             *(NPBool*)aValue = true;
    1117           0 :             return NPERR_NO_ERROR;
    1118             :         case NPNVSupportsWindowless:
    1119           0 :             *(NPBool*)aValue = true;
    1120           0 :             return NPERR_NO_ERROR;
    1121             : #if defined(MOZ_WIDGET_GTK)
    1122             :         case NPNVxDisplay: {
    1123           0 :             if (!aNPP) {
    1124           0 :                 return NPERR_INVALID_INSTANCE_ERROR;
    1125             :             }
    1126           0 :             return InstCast(aNPP)->NPN_GetValue(aVariable, aValue);
    1127             :         }
    1128             :         case NPNVxtAppContext:
    1129           0 :             return NPERR_GENERIC_ERROR;
    1130             : #endif
    1131             :         default: {
    1132           0 :             if (aNPP) {
    1133           0 :                 return InstCast(aNPP)->NPN_GetValue(aVariable, aValue);
    1134             :             }
    1135             : 
    1136           0 :             NS_WARNING("Null NPP!");
    1137           0 :             return NPERR_INVALID_INSTANCE_ERROR;
    1138             :         }
    1139             :     }
    1140             : 
    1141             :     NS_NOTREACHED("Shouldn't get here!");
    1142             :     return NPERR_GENERIC_ERROR;
    1143             : }
    1144             : 
    1145             : NPError
    1146           0 : _setvalue(NPP aNPP,
    1147             :           NPPVariable aVariable,
    1148             :           void* aValue)
    1149             : {
    1150           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1151           0 :     ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM);
    1152           0 :     return InstCast(aNPP)->NPN_SetValue(aVariable, aValue);
    1153             : }
    1154             : 
    1155             : NPError
    1156           0 : _geturl(NPP aNPP,
    1157             :         const char* aRelativeURL,
    1158             :         const char* aTarget)
    1159             : {
    1160           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1161           0 :     ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM);
    1162             : 
    1163             :     NPError err;
    1164           0 :     InstCast(aNPP)->CallNPN_GetURL(NullableString(aRelativeURL),
    1165           0 :                                    NullableString(aTarget), &err);
    1166           0 :     return err;
    1167             : }
    1168             : 
    1169             : NPError
    1170           0 : _posturlnotify(NPP aNPP,
    1171             :                const char* aRelativeURL,
    1172             :                const char* aTarget,
    1173             :                uint32_t aLength,
    1174             :                const char* aBuffer,
    1175             :                NPBool aIsFile,
    1176             :                void* aNotifyData)
    1177             : {
    1178           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1179           0 :     ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM);
    1180             : 
    1181           0 :     if (!aBuffer)
    1182           0 :         return NPERR_INVALID_PARAM;
    1183             : 
    1184           0 :     if (aIsFile) {
    1185           0 :       PLUGIN_LOG_DEBUG(("NPN_PostURLNotify with file=true is no longer supported"));
    1186           0 :       return NPERR_GENERIC_ERROR;
    1187             :     }
    1188             : 
    1189           0 :     nsCString url = NullableString(aRelativeURL);
    1190           0 :     auto* sn = new StreamNotifyChild(url);
    1191             : 
    1192             :     NPError err;
    1193           0 :     InstCast(aNPP)->CallPStreamNotifyConstructor(
    1194           0 :         sn, url, NullableString(aTarget), true,
    1195           0 :         nsCString(aBuffer, aLength), aIsFile, &err);
    1196             : 
    1197           0 :     if (NPERR_NO_ERROR == err) {
    1198             :         // If NPN_PostURLNotify fails, the parent will immediately send us
    1199             :         // a PStreamNotifyDestructor, which should not call NPP_URLNotify.
    1200           0 :         sn->SetValid(aNotifyData);
    1201             :     }
    1202             : 
    1203           0 :     return err;
    1204             : }
    1205             : 
    1206             : NPError
    1207           0 : _posturl(NPP aNPP,
    1208             :          const char* aRelativeURL,
    1209             :          const char* aTarget,
    1210             :          uint32_t aLength,
    1211             :          const char* aBuffer,
    1212             :          NPBool aIsFile)
    1213             : {
    1214           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1215           0 :     ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM);
    1216             : 
    1217           0 :     if (aIsFile) {
    1218           0 :       PLUGIN_LOG_DEBUG(("NPN_PostURL with file=true is no longer supported"));
    1219           0 :       return NPERR_GENERIC_ERROR;
    1220             :     }
    1221             :     NPError err;
    1222             :     // FIXME what should happen when |aBuffer| is null?
    1223           0 :     InstCast(aNPP)->CallNPN_PostURL(NullableString(aRelativeURL),
    1224           0 :                                     NullableString(aTarget),
    1225           0 :                                     nsDependentCString(aBuffer, aLength),
    1226           0 :                                     aIsFile, &err);
    1227           0 :     return err;
    1228             : }
    1229             : 
    1230             : 
    1231             : void
    1232           0 : _status(NPP aNPP,
    1233             :         const char* aMessage)
    1234             : {
    1235             :     // NPN_Status is no longer supported.
    1236           0 : }
    1237             : 
    1238             : void
    1239           0 : _memfree(void* aPtr)
    1240             : {
    1241           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1242           0 :     free(aPtr);
    1243           0 : }
    1244             : 
    1245             : uint32_t
    1246           0 : _memflush(uint32_t aSize)
    1247             : {
    1248           0 :     return 0;
    1249             : }
    1250             : 
    1251             : void
    1252           0 : _reloadplugins(NPBool aReloadPages)
    1253             : {
    1254           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1255           0 :     ENSURE_PLUGIN_THREAD_VOID();
    1256             : 
    1257             :     // Send the reload message to all modules. Chrome will need to reload from
    1258             :     // disk and content will need to request a new list of plugin tags from
    1259             :     // chrome.
    1260           0 :     PluginModuleChild::GetChrome()->SendNPN_ReloadPlugins(!!aReloadPages);
    1261             : }
    1262             : 
    1263             : void
    1264           0 : _invalidaterect(NPP aNPP,
    1265             :                 NPRect* aInvalidRect)
    1266             : {
    1267           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1268           0 :     ENSURE_PLUGIN_THREAD_VOID();
    1269             :     // nullptr check for nspluginwrapper (bug 548434)
    1270           0 :     if (aNPP) {
    1271           0 :         InstCast(aNPP)->InvalidateRect(aInvalidRect);
    1272             :     }
    1273             : }
    1274             : 
    1275             : void
    1276           0 : _invalidateregion(NPP aNPP,
    1277             :                   NPRegion aInvalidRegion)
    1278             : {
    1279           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1280           0 :     ENSURE_PLUGIN_THREAD_VOID();
    1281           0 :     NS_WARNING("Not yet implemented!");
    1282             : }
    1283             : 
    1284             : void
    1285           0 : _forceredraw(NPP aNPP)
    1286             : {
    1287           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1288           0 :     ENSURE_PLUGIN_THREAD_VOID();
    1289             : 
    1290             :     // We ignore calls to NPN_ForceRedraw. Such calls should
    1291             :     // never be necessary.
    1292             : }
    1293             : 
    1294             : const char*
    1295           0 : _useragent(NPP aNPP)
    1296             : {
    1297           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1298           0 :     ENSURE_PLUGIN_THREAD(nullptr);
    1299           0 :     return PluginModuleChild::GetChrome()->GetUserAgent();
    1300             : }
    1301             : 
    1302             : void*
    1303           0 : _memalloc(uint32_t aSize)
    1304             : {
    1305           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1306           0 :     return moz_xmalloc(aSize);
    1307             : }
    1308             : 
    1309             : // Deprecated entry points for the old Java plugin.
    1310             : void* /* OJI type: JRIEnv* */
    1311           0 : _getjavaenv(void)
    1312             : {
    1313           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1314           0 :     return 0;
    1315             : }
    1316             : 
    1317             : void* /* OJI type: jref */
    1318           0 : _getjavapeer(NPP aNPP)
    1319             : {
    1320           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1321           0 :     return 0;
    1322             : }
    1323             : 
    1324             : bool
    1325           0 : _invoke(NPP aNPP,
    1326             :         NPObject* aNPObj,
    1327             :         NPIdentifier aMethod,
    1328             :         const NPVariant* aArgs,
    1329             :         uint32_t aArgCount,
    1330             :         NPVariant* aResult)
    1331             : {
    1332           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1333           0 :     ENSURE_PLUGIN_THREAD(false);
    1334             : 
    1335           0 :     if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->invoke)
    1336           0 :         return false;
    1337             : 
    1338           0 :     return aNPObj->_class->invoke(aNPObj, aMethod, aArgs, aArgCount, aResult);
    1339             : }
    1340             : 
    1341             : bool
    1342           0 : _invokedefault(NPP aNPP,
    1343             :                NPObject* aNPObj,
    1344             :                const NPVariant* aArgs,
    1345             :                uint32_t aArgCount,
    1346             :                NPVariant* aResult)
    1347             : {
    1348           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1349           0 :     ENSURE_PLUGIN_THREAD(false);
    1350             : 
    1351           0 :     if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->invokeDefault)
    1352           0 :         return false;
    1353             : 
    1354           0 :     return aNPObj->_class->invokeDefault(aNPObj, aArgs, aArgCount, aResult);
    1355             : }
    1356             : 
    1357             : bool
    1358           0 : _evaluate(NPP aNPP,
    1359             :           NPObject* aObject,
    1360             :           NPString* aScript,
    1361             :           NPVariant* aResult)
    1362             : {
    1363           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1364           0 :     ENSURE_PLUGIN_THREAD(false);
    1365             : 
    1366           0 :     if (!(aNPP && aObject && aScript && aResult)) {
    1367           0 :         NS_ERROR("Bad arguments!");
    1368           0 :         return false;
    1369             :     }
    1370             : 
    1371             :     PluginScriptableObjectChild* actor =
    1372           0 :       InstCast(aNPP)->GetActorForNPObject(aObject);
    1373           0 :     if (!actor) {
    1374           0 :         NS_ERROR("Failed to create actor?!");
    1375           0 :         return false;
    1376             :     }
    1377             : 
    1378             : #ifdef XP_WIN
    1379             :     if (gDelayFlashFocusReplyUntilEval) {
    1380             :         ReplyMessage(0);
    1381             :         gDelayFlashFocusReplyUntilEval = false;
    1382             :     }
    1383             : #endif
    1384             : 
    1385           0 :     return actor->Evaluate(aScript, aResult);
    1386             : }
    1387             : 
    1388             : bool
    1389           0 : _getproperty(NPP aNPP,
    1390             :              NPObject* aNPObj,
    1391             :              NPIdentifier aPropertyName,
    1392             :              NPVariant* aResult)
    1393             : {
    1394           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1395           0 :     ENSURE_PLUGIN_THREAD(false);
    1396             : 
    1397           0 :     if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->getProperty)
    1398           0 :         return false;
    1399             : 
    1400           0 :     return aNPObj->_class->getProperty(aNPObj, aPropertyName, aResult);
    1401             : }
    1402             : 
    1403             : bool
    1404           0 : _setproperty(NPP aNPP,
    1405             :              NPObject* aNPObj,
    1406             :              NPIdentifier aPropertyName,
    1407             :              const NPVariant* aValue)
    1408             : {
    1409           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1410           0 :     ENSURE_PLUGIN_THREAD(false);
    1411             : 
    1412           0 :     if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->setProperty)
    1413           0 :         return false;
    1414             : 
    1415           0 :     return aNPObj->_class->setProperty(aNPObj, aPropertyName, aValue);
    1416             : }
    1417             : 
    1418             : bool
    1419           0 : _removeproperty(NPP aNPP,
    1420             :                 NPObject* aNPObj,
    1421             :                 NPIdentifier aPropertyName)
    1422             : {
    1423           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1424           0 :     ENSURE_PLUGIN_THREAD(false);
    1425             : 
    1426           0 :     if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->removeProperty)
    1427           0 :         return false;
    1428             : 
    1429           0 :     return aNPObj->_class->removeProperty(aNPObj, aPropertyName);
    1430             : }
    1431             : 
    1432             : bool
    1433           0 : _hasproperty(NPP aNPP,
    1434             :              NPObject* aNPObj,
    1435             :              NPIdentifier aPropertyName)
    1436             : {
    1437           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1438           0 :     ENSURE_PLUGIN_THREAD(false);
    1439             : 
    1440           0 :     if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->hasProperty)
    1441           0 :         return false;
    1442             : 
    1443           0 :     return aNPObj->_class->hasProperty(aNPObj, aPropertyName);
    1444             : }
    1445             : 
    1446             : bool
    1447           0 : _hasmethod(NPP aNPP,
    1448             :            NPObject* aNPObj,
    1449             :            NPIdentifier aMethodName)
    1450             : {
    1451           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1452           0 :     ENSURE_PLUGIN_THREAD(false);
    1453             : 
    1454           0 :     if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->hasMethod)
    1455           0 :         return false;
    1456             : 
    1457           0 :     return aNPObj->_class->hasMethod(aNPObj, aMethodName);
    1458             : }
    1459             : 
    1460             : bool
    1461           0 : _enumerate(NPP aNPP,
    1462             :            NPObject* aNPObj,
    1463             :            NPIdentifier** aIdentifiers,
    1464             :            uint32_t* aCount)
    1465             : {
    1466           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1467           0 :     ENSURE_PLUGIN_THREAD(false);
    1468             : 
    1469           0 :     if (!aNPP || !aNPObj || !aNPObj->_class)
    1470           0 :         return false;
    1471             : 
    1472           0 :     if (!NP_CLASS_STRUCT_VERSION_HAS_ENUM(aNPObj->_class) ||
    1473           0 :         !aNPObj->_class->enumerate) {
    1474           0 :         *aIdentifiers = 0;
    1475           0 :         *aCount = 0;
    1476           0 :         return true;
    1477             :     }
    1478             : 
    1479           0 :     return aNPObj->_class->enumerate(aNPObj, aIdentifiers, aCount);
    1480             : }
    1481             : 
    1482             : bool
    1483           0 : _construct(NPP aNPP,
    1484             :            NPObject* aNPObj,
    1485             :            const NPVariant* aArgs,
    1486             :            uint32_t aArgCount,
    1487             :            NPVariant* aResult)
    1488             : {
    1489           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1490           0 :     ENSURE_PLUGIN_THREAD(false);
    1491             : 
    1492           0 :     if (!aNPP || !aNPObj || !aNPObj->_class ||
    1493           0 :         !NP_CLASS_STRUCT_VERSION_HAS_CTOR(aNPObj->_class) ||
    1494           0 :         !aNPObj->_class->construct) {
    1495           0 :         return false;
    1496             :     }
    1497             : 
    1498           0 :     return aNPObj->_class->construct(aNPObj, aArgs, aArgCount, aResult);
    1499             : }
    1500             : 
    1501             : void
    1502           0 : _releasevariantvalue(NPVariant* aVariant)
    1503             : {
    1504           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1505             :     // Only assert plugin thread here for consistency with in-process plugins.
    1506           0 :     AssertPluginThread();
    1507             : 
    1508           0 :     if (NPVARIANT_IS_STRING(*aVariant)) {
    1509           0 :         NPString str = NPVARIANT_TO_STRING(*aVariant);
    1510           0 :         free(const_cast<NPUTF8*>(str.UTF8Characters));
    1511             :     }
    1512           0 :     else if (NPVARIANT_IS_OBJECT(*aVariant)) {
    1513           0 :         NPObject* object = NPVARIANT_TO_OBJECT(*aVariant);
    1514           0 :         if (object) {
    1515           0 :             PluginModuleChild::NPN_ReleaseObject(object);
    1516             :         }
    1517             :     }
    1518           0 :     VOID_TO_NPVARIANT(*aVariant);
    1519           0 : }
    1520             : 
    1521             : void
    1522           0 : _setexception(NPObject* aNPObj,
    1523             :               const NPUTF8* aMessage)
    1524             : {
    1525           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1526           0 :     ENSURE_PLUGIN_THREAD_VOID();
    1527             : 
    1528             :     // Do nothing. We no longer support this API.
    1529             : }
    1530             : 
    1531             : void
    1532           0 : _pushpopupsenabledstate(NPP aNPP,
    1533             :                         NPBool aEnabled)
    1534             : {
    1535           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1536           0 :     ENSURE_PLUGIN_THREAD_VOID();
    1537             : 
    1538           0 :     InstCast(aNPP)->CallNPN_PushPopupsEnabledState(aEnabled ? true : false);
    1539             : }
    1540             : 
    1541             : void
    1542           0 : _poppopupsenabledstate(NPP aNPP)
    1543             : {
    1544           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1545           0 :     ENSURE_PLUGIN_THREAD_VOID();
    1546             : 
    1547           0 :     InstCast(aNPP)->CallNPN_PopPopupsEnabledState();
    1548             : }
    1549             : 
    1550             : void
    1551           0 : _pluginthreadasynccall(NPP aNPP,
    1552             :                        PluginThreadCallback aFunc,
    1553             :                        void* aUserData)
    1554             : {
    1555           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1556           0 :     if (!aFunc)
    1557           0 :         return;
    1558             : 
    1559           0 :     InstCast(aNPP)->AsyncCall(aFunc, aUserData);
    1560             : }
    1561             : 
    1562             : NPError
    1563           0 : _getvalueforurl(NPP npp, NPNURLVariable variable, const char *url,
    1564             :                 char **value, uint32_t *len)
    1565             : {
    1566           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1567           0 :     AssertPluginThread();
    1568             : 
    1569           0 :     if (!url)
    1570           0 :         return NPERR_INVALID_URL;
    1571             : 
    1572           0 :     if (!npp || !value || !len)
    1573           0 :         return NPERR_INVALID_PARAM;
    1574             : 
    1575           0 :     if (variable == NPNURLVProxy) {
    1576           0 :         nsCString v;
    1577             :         NPError result;
    1578           0 :         InstCast(npp)->
    1579           0 :             CallNPN_GetValueForURL(variable, nsCString(url), &v, &result);
    1580           0 :         if (NPERR_NO_ERROR == result) {
    1581           0 :             *value = ToNewCString(v);
    1582           0 :             *len = v.Length();
    1583             :         }
    1584           0 :         return result;
    1585             :     }
    1586             : 
    1587           0 :     return NPERR_INVALID_PARAM;
    1588             : }
    1589             : 
    1590             : NPError
    1591           0 : _setvalueforurl(NPP npp, NPNURLVariable variable, const char *url,
    1592             :                 const char *value, uint32_t len)
    1593             : {
    1594           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1595           0 :     AssertPluginThread();
    1596             : 
    1597           0 :     if (!value)
    1598           0 :         return NPERR_INVALID_PARAM;
    1599             : 
    1600           0 :     if (!url)
    1601           0 :         return NPERR_INVALID_URL;
    1602             : 
    1603           0 :     if (variable == NPNURLVProxy) {
    1604             :         NPError result;
    1605           0 :         InstCast(npp)->CallNPN_SetValueForURL(variable, nsCString(url),
    1606           0 :                                               nsDependentCString(value, len),
    1607           0 :                                               &result);
    1608           0 :         return result;
    1609             :     }
    1610             : 
    1611           0 :     return NPERR_INVALID_PARAM;
    1612             : }
    1613             : 
    1614             : 
    1615             : uint32_t
    1616           0 : _scheduletimer(NPP npp, uint32_t interval, NPBool repeat,
    1617             :                void (*timerFunc)(NPP npp, uint32_t timerID))
    1618             : {
    1619           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1620           0 :     AssertPluginThread();
    1621           0 :     return InstCast(npp)->ScheduleTimer(interval, repeat, timerFunc);
    1622             : }
    1623             : 
    1624             : void
    1625           0 : _unscheduletimer(NPP npp, uint32_t timerID)
    1626             : {
    1627           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1628           0 :     AssertPluginThread();
    1629           0 :     InstCast(npp)->UnscheduleTimer(timerID);
    1630           0 : }
    1631             : 
    1632             : 
    1633             : #ifdef OS_MACOSX
    1634             : static void ProcessBrowserEvents(void* pluginModule) {
    1635             :     PluginModuleChild* pmc = static_cast<PluginModuleChild*>(pluginModule);
    1636             : 
    1637             :     if (!pmc)
    1638             :         return;
    1639             : 
    1640             :     pmc->CallProcessSomeEvents();
    1641             : }
    1642             : #endif
    1643             : 
    1644             : NPError
    1645           0 : _popupcontextmenu(NPP instance, NPMenu* menu)
    1646             : {
    1647           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1648           0 :     AssertPluginThread();
    1649             : 
    1650             : #ifdef MOZ_WIDGET_COCOA
    1651             :     double pluginX, pluginY;
    1652             :     double screenX, screenY;
    1653             : 
    1654             :     const NPCocoaEvent* currentEvent = InstCast(instance)->getCurrentEvent();
    1655             :     if (!currentEvent) {
    1656             :         return NPERR_GENERIC_ERROR;
    1657             :     }
    1658             : 
    1659             :     // Ensure that the events has an x/y value.
    1660             :     if (currentEvent->type != NPCocoaEventMouseDown    &&
    1661             :         currentEvent->type != NPCocoaEventMouseUp      &&
    1662             :         currentEvent->type != NPCocoaEventMouseMoved   &&
    1663             :         currentEvent->type != NPCocoaEventMouseEntered &&
    1664             :         currentEvent->type != NPCocoaEventMouseExited  &&
    1665             :         currentEvent->type != NPCocoaEventMouseDragged) {
    1666             :         return NPERR_GENERIC_ERROR;
    1667             :     }
    1668             : 
    1669             :     pluginX = currentEvent->data.mouse.pluginX;
    1670             :     pluginY = currentEvent->data.mouse.pluginY;
    1671             : 
    1672             :     if ((pluginX < 0.0) || (pluginY < 0.0))
    1673             :         return NPERR_GENERIC_ERROR;
    1674             : 
    1675             :     NPBool success = _convertpoint(instance,
    1676             :                                   pluginX,  pluginY, NPCoordinateSpacePlugin,
    1677             :                                  &screenX, &screenY, NPCoordinateSpaceScreen);
    1678             : 
    1679             :     if (success) {
    1680             :         return mozilla::plugins::PluginUtilsOSX::ShowCocoaContextMenu(menu,
    1681             :                                     screenX, screenY,
    1682             :                                     InstCast(instance)->Manager(),
    1683             :                                     ProcessBrowserEvents);
    1684             :     } else {
    1685             :         NS_WARNING("Convertpoint failed, could not created contextmenu.");
    1686             :         return NPERR_GENERIC_ERROR;
    1687             :     }
    1688             : 
    1689             : #else
    1690           0 :     NS_WARNING("Not supported on this platform!");
    1691           0 :     return NPERR_GENERIC_ERROR;
    1692             : #endif
    1693             : }
    1694             : 
    1695             : NPBool
    1696           0 : _convertpoint(NPP instance,
    1697             :               double sourceX, double sourceY, NPCoordinateSpace sourceSpace,
    1698             :               double *destX, double *destY, NPCoordinateSpace destSpace)
    1699             : {
    1700           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1701           0 :     if (!IsPluginThread()) {
    1702           0 :         NS_WARNING("Not running on the plugin's main thread!");
    1703           0 :         return false;
    1704             :     }
    1705             : 
    1706           0 :     double rDestX = 0;
    1707           0 :     bool ignoreDestX = !destX;
    1708           0 :     double rDestY = 0;
    1709           0 :     bool ignoreDestY = !destY;
    1710           0 :     bool result = false;
    1711           0 :     InstCast(instance)->CallNPN_ConvertPoint(sourceX, ignoreDestX, sourceY, ignoreDestY, sourceSpace, destSpace,
    1712           0 :                                              &rDestX,  &rDestY, &result);
    1713           0 :     if (result) {
    1714           0 :         if (destX)
    1715           0 :             *destX = rDestX;
    1716           0 :         if (destY)
    1717           0 :             *destY = rDestY;
    1718             :     }
    1719             : 
    1720           0 :     return result;
    1721             : }
    1722             : 
    1723             : void
    1724           0 : _urlredirectresponse(NPP instance, void* notifyData, NPBool allow)
    1725             : {
    1726           0 :     InstCast(instance)->NPN_URLRedirectResponse(notifyData, allow);
    1727           0 : }
    1728             : 
    1729             : NPError
    1730           0 : _initasyncsurface(NPP instance, NPSize *size,
    1731             :                   NPImageFormat format, void *initData,
    1732             :                   NPAsyncSurface *surface)
    1733             : {
    1734           0 :     return InstCast(instance)->NPN_InitAsyncSurface(size, format, initData, surface);
    1735             : }
    1736             : 
    1737             : NPError
    1738           0 : _finalizeasyncsurface(NPP instance, NPAsyncSurface *surface)
    1739             : {
    1740           0 :     return InstCast(instance)->NPN_FinalizeAsyncSurface(surface);
    1741             : }
    1742             : 
    1743             : void
    1744           0 : _setcurrentasyncsurface(NPP instance, NPAsyncSurface *surface, NPRect *changed)
    1745             : {
    1746           0 :     InstCast(instance)->NPN_SetCurrentAsyncSurface(surface, changed);
    1747           0 : }
    1748             : 
    1749             : } /* namespace child */
    1750             : } /* namespace plugins */
    1751             : } /* namespace mozilla */
    1752             : 
    1753             : //-----------------------------------------------------------------------------
    1754             : 
    1755             : mozilla::ipc::IPCResult
    1756           0 : PluginModuleChild::RecvSettingChanged(const PluginSettings& aSettings)
    1757             : {
    1758           0 :     mCachedSettings = aSettings;
    1759           0 :     return IPC_OK();
    1760             : }
    1761             : 
    1762             : mozilla::ipc::IPCResult
    1763           0 : PluginModuleChild::AnswerNP_GetEntryPoints(NPError* _retval)
    1764             : {
    1765           0 :     PLUGIN_LOG_DEBUG_METHOD;
    1766           0 :     AssertPluginThread();
    1767           0 :     MOZ_ASSERT(mIsChrome);
    1768             : 
    1769             : #if defined(OS_LINUX) || defined(OS_BSD) || defined(OS_SOLARIS)
    1770           0 :     return IPC_OK();
    1771             : #elif defined(OS_WIN) || defined(OS_MACOSX)
    1772             :     *_retval = mGetEntryPointsFunc(&mFunctions);
    1773             :     return IPC_OK();
    1774             : #else
    1775             : #  error Please implement me for your platform
    1776             : #endif
    1777             : }
    1778             : 
    1779             : mozilla::ipc::IPCResult
    1780           0 : PluginModuleChild::AnswerNP_Initialize(const PluginSettings& aSettings, NPError* rv)
    1781             : {
    1782           0 :     *rv = DoNP_Initialize(aSettings);
    1783           0 :     return IPC_OK();
    1784             : }
    1785             : 
    1786             : NPError
    1787           0 : PluginModuleChild::DoNP_Initialize(const PluginSettings& aSettings)
    1788             : {
    1789           0 :     PLUGIN_LOG_DEBUG_METHOD;
    1790           0 :     AssertPluginThread();
    1791           0 :     MOZ_ASSERT(mIsChrome);
    1792             : 
    1793           0 :     mCachedSettings = aSettings;
    1794             : 
    1795             : #ifdef OS_WIN
    1796             :     SetEventHooks();
    1797             : #endif
    1798             : 
    1799             : #ifdef MOZ_X11
    1800             :     // Send the parent our X socket to act as a proxy reference for our X
    1801             :     // resources.
    1802           0 :     int xSocketFd = ConnectionNumber(DefaultXDisplay());
    1803           0 :     SendBackUpXResources(FileDescriptor(xSocketFd));
    1804             : #endif
    1805             : 
    1806             :     NPError result;
    1807             : #if defined(OS_LINUX) || defined(OS_BSD) || defined(OS_SOLARIS)
    1808           0 :     result = mInitializeFunc(&sBrowserFuncs, &mFunctions);
    1809             : #elif defined(OS_WIN) || defined(OS_MACOSX)
    1810             :     result = mInitializeFunc(&sBrowserFuncs);
    1811             : #else
    1812             : #  error Please implement me for your platform
    1813             : #endif
    1814             : 
    1815           0 :     return result;
    1816             : }
    1817             : 
    1818             : #if defined(XP_WIN)
    1819             : 
    1820             : // Windows 8 RTM (kernelbase's version is 6.2.9200.16384) doesn't call
    1821             : // CreateFileW from CreateFileA.
    1822             : // So we hook CreateFileA too to use CreateFileW hook.
    1823             : 
    1824             : static HANDLE WINAPI
    1825             : CreateFileAHookFn(LPCSTR fname, DWORD access, DWORD share,
    1826             :                   LPSECURITY_ATTRIBUTES security, DWORD creation, DWORD flags,
    1827             :                   HANDLE ftemplate)
    1828             : {
    1829             :     while (true) { // goto out
    1830             :         // Our hook is for mms.cfg into \Windows\System32\Macromed\Flash
    1831             :         // We don't requrie supporting too long path.
    1832             :         WCHAR unicodeName[MAX_PATH];
    1833             :         size_t len = strlen(fname);
    1834             : 
    1835             :         if (len >= MAX_PATH) {
    1836             :             break;
    1837             :         }
    1838             : 
    1839             :         // We call to CreateFileW for workaround of Windows 8 RTM
    1840             :         int newLen = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, fname,
    1841             :                                          len, unicodeName, MAX_PATH);
    1842             :         if (newLen == 0 || newLen >= MAX_PATH) {
    1843             :             break;
    1844             :         }
    1845             :         unicodeName[newLen] = '\0';
    1846             : 
    1847             :         return CreateFileW(unicodeName, access, share, security, creation, flags, ftemplate);
    1848             :     }
    1849             : 
    1850             :     return sCreateFileAStub(fname, access, share, security, creation, flags,
    1851             :                             ftemplate);
    1852             : }
    1853             : 
    1854             : static bool
    1855             : GetLocalLowTempPath(size_t aLen, LPWSTR aPath)
    1856             : {
    1857             :     NS_NAMED_LITERAL_STRING(tempname, "\\Temp");
    1858             :     LPWSTR path;
    1859             :     if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_LocalAppDataLow, 0,
    1860             :                                        nullptr, &path))) {
    1861             :         if (wcslen(path) + tempname.Length() < aLen) {
    1862             :             wcscpy(aPath, path);
    1863             :             wcscat(aPath, tempname.get());
    1864             :             ::CoTaskMemFree(path);
    1865             :             return true;
    1866             :         }
    1867             :         ::CoTaskMemFree(path);
    1868             :     }
    1869             : 
    1870             :     // XP doesn't support SHGetKnownFolderPath and LocalLow
    1871             :     if (!GetTempPathW(aLen, aPath)) {
    1872             :         return false;
    1873             :     }
    1874             :     return true;
    1875             : }
    1876             : 
    1877             : HANDLE WINAPI
    1878             : CreateFileWHookFn(LPCWSTR fname, DWORD access, DWORD share,
    1879             :                   LPSECURITY_ATTRIBUTES security, DWORD creation, DWORD flags,
    1880             :                   HANDLE ftemplate)
    1881             : {
    1882             :     static const WCHAR kConfigFile[] = L"mms.cfg";
    1883             :     static const size_t kConfigLength = ArrayLength(kConfigFile) - 1;
    1884             : 
    1885             :     while (true) { // goto out, in sheep's clothing
    1886             :         size_t len = wcslen(fname);
    1887             :         if (len < kConfigLength) {
    1888             :             break;
    1889             :         }
    1890             :         if (wcscmp(fname + len - kConfigLength, kConfigFile) != 0) {
    1891             :             break;
    1892             :         }
    1893             : 
    1894             :         // This is the config file we want to rewrite
    1895             :         WCHAR tempPath[MAX_PATH+1];
    1896             :         if (GetLocalLowTempPath(MAX_PATH, tempPath) == 0) {
    1897             :             break;
    1898             :         }
    1899             :         WCHAR tempFile[MAX_PATH+1];
    1900             :         if (GetTempFileNameW(tempPath, L"fx", 0, tempFile) == 0) {
    1901             :             break;
    1902             :         }
    1903             :         HANDLE replacement =
    1904             :             sCreateFileWStub(tempFile, GENERIC_READ | GENERIC_WRITE, share,
    1905             :                              security, TRUNCATE_EXISTING,
    1906             :                              FILE_ATTRIBUTE_TEMPORARY |
    1907             :                                FILE_FLAG_DELETE_ON_CLOSE,
    1908             :                              NULL);
    1909             :         if (replacement == INVALID_HANDLE_VALUE) {
    1910             :             break;
    1911             :         }
    1912             : 
    1913             :         HANDLE original = sCreateFileWStub(fname, access, share, security,
    1914             :                                            creation, flags, ftemplate);
    1915             :         if (original != INVALID_HANDLE_VALUE) {
    1916             :             // copy original to replacement
    1917             :             static const size_t kBufferSize = 1024;
    1918             :             char buffer[kBufferSize];
    1919             :             DWORD bytes;
    1920             :             while (ReadFile(original, buffer, kBufferSize, &bytes, NULL)) {
    1921             :                 if (bytes == 0) {
    1922             :                     break;
    1923             :                 }
    1924             :                 DWORD wbytes;
    1925             :                 WriteFile(replacement, buffer, bytes, &wbytes, NULL);
    1926             :                 if (bytes < kBufferSize) {
    1927             :                     break;
    1928             :                 }
    1929             :             }
    1930             :             CloseHandle(original);
    1931             :         }
    1932             :         static const char kSettingString[] = "\nProtectedMode=0\n";
    1933             :         DWORD wbytes;
    1934             :         WriteFile(replacement, static_cast<const void*>(kSettingString),
    1935             :                   sizeof(kSettingString) - 1, &wbytes, NULL);
    1936             :         SetFilePointer(replacement, 0, NULL, FILE_BEGIN);
    1937             :         return replacement;
    1938             :     }
    1939             :     return sCreateFileWStub(fname, access, share, security, creation, flags,
    1940             :                             ftemplate);
    1941             : }
    1942             : 
    1943             : void
    1944             : PluginModuleChild::HookProtectedMode()
    1945             : {
    1946             :     sKernel32Intercept.Init("kernel32.dll");
    1947             :     sKernel32Intercept.AddHook("CreateFileW",
    1948             :                                reinterpret_cast<intptr_t>(CreateFileWHookFn),
    1949             :                                (void**) &sCreateFileWStub);
    1950             :     sKernel32Intercept.AddHook("CreateFileA",
    1951             :                                reinterpret_cast<intptr_t>(CreateFileAHookFn),
    1952             :                                (void**) &sCreateFileAStub);
    1953             : }
    1954             : 
    1955             : BOOL WINAPI
    1956             : PMCGetWindowInfoHook(HWND hWnd, PWINDOWINFO pwi)
    1957             : {
    1958             :   if (!pwi)
    1959             :       return FALSE;
    1960             : 
    1961             :   if (!sGetWindowInfoPtrStub) {
    1962             :      NS_ASSERTION(FALSE, "Something is horribly wrong in PMCGetWindowInfoHook!");
    1963             :      return FALSE;
    1964             :   }
    1965             : 
    1966             :   if (!sBrowserHwnd) {
    1967             :       wchar_t szClass[20];
    1968             :       if (GetClassNameW(hWnd, szClass, ArrayLength(szClass)) &&
    1969             :           !wcscmp(szClass, kMozillaWindowClass)) {
    1970             :           sBrowserHwnd = hWnd;
    1971             :       }
    1972             :   }
    1973             :   // Oddity: flash does strange rect comparisons for mouse input destined for
    1974             :   // it's internal settings window. Post removing sub widgets for tabs, touch
    1975             :   // this up so they get the rect they expect.
    1976             :   // XXX potentially tie this to a specific major version?
    1977             :   BOOL result = sGetWindowInfoPtrStub(hWnd, pwi);
    1978             :   if (sBrowserHwnd && sBrowserHwnd == hWnd)
    1979             :       pwi->rcWindow = pwi->rcClient;
    1980             :   return result;
    1981             : }
    1982             : 
    1983             : SHORT WINAPI PMCGetKeyState(int aVirtKey);
    1984             : 
    1985             : // Runnable that performs GetKeyState on the main thread so that it can be
    1986             : // synchronously run on the PluginModuleParent via IPC.
    1987             : // The task alerts the given semaphore when it is finished.
    1988             : class GetKeyStateTask : public Runnable
    1989             : {
    1990             :     SHORT* mKeyState;
    1991             :     int mVirtKey;
    1992             :     HANDLE mSemaphore;
    1993             : 
    1994             : public:
    1995             :     explicit GetKeyStateTask(int aVirtKey, HANDLE aSemaphore, SHORT* aKeyState) :
    1996             :         Runnable("GetKeyStateTask"),
    1997             :         mVirtKey(aVirtKey),
    1998             :         mSemaphore(aSemaphore),
    1999             :         mKeyState(aKeyState)
    2000             :     {}
    2001             : 
    2002             :     NS_IMETHOD Run() override
    2003             :     {
    2004             :         PLUGIN_LOG_DEBUG_METHOD;
    2005             :         AssertPluginThread();
    2006             :         *mKeyState = PMCGetKeyState(mVirtKey);
    2007             :         if (!ReleaseSemaphore(mSemaphore, 1, nullptr)) {
    2008             :             return NS_ERROR_FAILURE;
    2009             :         }
    2010             :         return NS_OK;
    2011             :     }
    2012             : };
    2013             : 
    2014             : // static
    2015             : SHORT WINAPI
    2016             : PMCGetKeyState(int aVirtKey)
    2017             : {
    2018             :     if (!IsPluginThread()) {
    2019             :         // synchronously request the key state from the main thread
    2020             : 
    2021             :         // Start a semaphore at 0.  We Release the semaphore (bringing its count to 1)
    2022             :         // when the synchronous call is done.
    2023             :         HANDLE semaphore = CreateSemaphore(NULL, 0, 1, NULL);
    2024             :         if (semaphore == nullptr) {
    2025             :             MOZ_ASSERT(semaphore != nullptr);
    2026             :             return 0;
    2027             :         }
    2028             : 
    2029             :         SHORT keyState;
    2030             :         RefPtr<GetKeyStateTask> task = new GetKeyStateTask(aVirtKey, semaphore, &keyState);
    2031             :         ProcessChild::message_loop()->PostTask(task.forget());
    2032             :         DWORD err = WaitForSingleObject(semaphore, INFINITE);
    2033             :         if (err != WAIT_FAILED) {
    2034             :             CloseHandle(semaphore);
    2035             :             return keyState;
    2036             :         }
    2037             :         PLUGIN_LOG_DEBUG(("Error while waiting for GetKeyState semaphore: %d",
    2038             :                           GetLastError()));
    2039             :         MOZ_ASSERT(err != WAIT_FAILED);
    2040             :         CloseHandle(semaphore);
    2041             :         return 0;
    2042             :     }
    2043             :     PluginModuleChild* chromeInstance = PluginModuleChild::GetChrome();
    2044             :     if (chromeInstance) {
    2045             :         int16_t ret = 0;
    2046             :         if (chromeInstance->CallGetKeyState(aVirtKey, &ret)) {
    2047             :           return ret;
    2048             :         }
    2049             :     }
    2050             :     return sGetKeyStatePtrStub(aVirtKey);
    2051             : }
    2052             : 
    2053             : class PluginThreadTaskData
    2054             : {
    2055             : public:
    2056             :     virtual bool RunTask() = 0;
    2057             : };
    2058             : 
    2059             : // Runnable that performs a task on the main thread so that the call can be
    2060             : // synchronously run on the PluginModuleParent via IPC.
    2061             : // The task alerts the given semaphore when it is finished.
    2062             : class PluginThreadTask : public Runnable
    2063             : {
    2064             :     bool mSuccess;
    2065             :     PluginThreadTaskData* mTaskData;
    2066             :     HANDLE mSemaphore;
    2067             : 
    2068             : public:
    2069             :     explicit PluginThreadTask(PluginThreadTaskData* aTaskData,
    2070             :                               HANDLE aSemaphore) :
    2071             :         Runnable("PluginThreadTask"), mTaskData(aTaskData),
    2072             :         mSemaphore(aSemaphore), mSuccess(false)
    2073             :     {}
    2074             : 
    2075             :     NS_IMETHOD Run() override
    2076             :     {
    2077             :         PLUGIN_LOG_DEBUG_METHOD;
    2078             :         AssertPluginThread();
    2079             :         mSuccess = mTaskData->RunTask();
    2080             :         if (!ReleaseSemaphore(mSemaphore, 1, nullptr)) {
    2081             :             return NS_ERROR_FAILURE;
    2082             :         }
    2083             :         return NS_OK;
    2084             :     }
    2085             : 
    2086             :     bool Success() { return mSuccess; }
    2087             : };
    2088             : 
    2089             : // static
    2090             : BOOL
    2091             : PostToPluginThread(PluginThreadTaskData* aTaskData)
    2092             : {
    2093             :     MOZ_ASSERT(!IsPluginThread());
    2094             : 
    2095             :     // Synchronously run GetFileNameTask from the main thread.
    2096             :     // Start a semaphore at 0.  We release the semaphore (bringing its
    2097             :     // count to 1) when the synchronous call is done.
    2098             :     nsAutoHandle semaphore(CreateSemaphore(NULL, 0, 1, NULL));
    2099             :     if (semaphore == nullptr) {
    2100             :         MOZ_ASSERT(semaphore != nullptr);
    2101             :         return FALSE;
    2102             :     }
    2103             : 
    2104             :     RefPtr<PluginThreadTask> task = new PluginThreadTask(aTaskData, semaphore);
    2105             :     ProcessChild::message_loop()->PostTask(do_AddRef(task));
    2106             :     DWORD err = WaitForSingleObject(semaphore, INFINITE);
    2107             :     if (err != WAIT_FAILED) {
    2108             :         return task->Success();
    2109             :     }
    2110             :     PLUGIN_LOG_DEBUG(("Error while waiting for semaphore: %d",
    2111             :                       GetLastError()));
    2112             :     MOZ_ASSERT(err != WAIT_FAILED);
    2113             :     return FALSE;
    2114             : }
    2115             : 
    2116             : BOOL WINAPI PMCGetSaveFileNameW(LPOPENFILENAMEW lpofn);
    2117             : BOOL WINAPI PMCGetOpenFileNameW(LPOPENFILENAMEW lpofn);
    2118             : 
    2119             : class GetFileNameTaskData : public PluginThreadTaskData
    2120             : {
    2121             : public:
    2122             :     GetFileNameTaskData(GetFileNameFunc aFunc, void* aLpOpenFileName) :
    2123             :         mFunc(aFunc), mLpOpenFileName(aLpOpenFileName)
    2124             :     {}
    2125             : 
    2126             :     bool RunTask()
    2127             :     {
    2128             :         switch (mFunc) {
    2129             :         case OPEN_FUNC:
    2130             :             return PMCGetOpenFileNameW(static_cast<LPOPENFILENAMEW>(mLpOpenFileName));
    2131             :         case SAVE_FUNC:
    2132             :             return PMCGetSaveFileNameW(static_cast<LPOPENFILENAMEW>(mLpOpenFileName));
    2133             :         }
    2134             :         return false;
    2135             :     }
    2136             : 
    2137             : private:
    2138             :     GetFileNameFunc mFunc;
    2139             :     void* mLpOpenFileName;
    2140             : };
    2141             : 
    2142             : // static
    2143             : BOOL WINAPI
    2144             : PMCGetFileNameW(GetFileNameFunc aFunc, LPOPENFILENAMEW aLpofn)
    2145             : {
    2146             :     if (!IsPluginThread()) {
    2147             :         GetFileNameTaskData gfnData(aFunc, aLpofn);
    2148             :         return PostToPluginThread(&gfnData);
    2149             :     }
    2150             : 
    2151             :     PluginModuleChild* chromeInstance = PluginModuleChild::GetChrome();
    2152             :     if (chromeInstance) {
    2153             :         bool ret = FALSE;
    2154             :         OpenFileNameIPC inputOfn;
    2155             :         inputOfn.CopyFromOfn(aLpofn);
    2156             :         OpenFileNameRetIPC outputOfn;
    2157             :         if (chromeInstance->CallGetFileName(aFunc, inputOfn,
    2158             :                                             &outputOfn, &ret)) {
    2159             :             if (ret) {
    2160             :                 outputOfn.AddToOfn(aLpofn);
    2161             :             }
    2162             :         }
    2163             :         return ret;
    2164             :     }
    2165             : 
    2166             :     switch (aFunc) {
    2167             :     case OPEN_FUNC:
    2168             :         return sGetOpenFileNameWPtrStub(aLpofn);
    2169             :     case SAVE_FUNC:
    2170             :         return sGetSaveFileNameWPtrStub(aLpofn);
    2171             :     }
    2172             : 
    2173             :     MOZ_ASSERT_UNREACHABLE("Illegal GetFileNameFunc value");
    2174             :     return FALSE;
    2175             : }
    2176             : 
    2177             : // static
    2178             : BOOL WINAPI
    2179             : PMCGetSaveFileNameW(LPOPENFILENAMEW aLpofn)
    2180             : {
    2181             :     return PMCGetFileNameW(SAVE_FUNC, aLpofn);
    2182             : }
    2183             : // static
    2184             : BOOL WINAPI
    2185             : PMCGetOpenFileNameW(LPOPENFILENAMEW aLpofn)
    2186             : {
    2187             :     return PMCGetFileNameW(OPEN_FUNC, aLpofn);
    2188             : }
    2189             : 
    2190             : BOOL WINAPI PMCSetCursorPos(int x, int y);
    2191             : 
    2192             : class SetCursorPosTaskData : public PluginThreadTaskData
    2193             : {
    2194             : public:
    2195             :     SetCursorPosTaskData(int x, int y) : mX(x), mY(y) {}
    2196             :     bool RunTask() { return PMCSetCursorPos(mX, mY); }
    2197             : private:
    2198             :     int mX, mY;
    2199             : };
    2200             : 
    2201             : // static
    2202             : BOOL WINAPI
    2203             : PMCSetCursorPos(int x, int y)
    2204             : {
    2205             :     if (!IsPluginThread()) {
    2206             :         SetCursorPosTaskData scpData(x, y);
    2207             :         return PostToPluginThread(&scpData);
    2208             :     }
    2209             : 
    2210             :     PluginModuleChild* chromeInstance = PluginModuleChild::GetChrome();
    2211             :     if (chromeInstance) {
    2212             :         bool ret = FALSE;
    2213             :         chromeInstance->CallSetCursorPos(x, y, &ret);
    2214             :         return ret;
    2215             :     }
    2216             : 
    2217             :     return sSetCursorPosPtrStub(x, y);
    2218             : }
    2219             : 
    2220             : 
    2221             : #endif
    2222             : 
    2223             : PPluginInstanceChild*
    2224           0 : PluginModuleChild::AllocPPluginInstanceChild(const nsCString& aMimeType,
    2225             :                                              const InfallibleTArray<nsCString>& aNames,
    2226             :                                              const InfallibleTArray<nsCString>& aValues)
    2227             : {
    2228           0 :     PLUGIN_LOG_DEBUG_METHOD;
    2229           0 :     AssertPluginThread();
    2230             : 
    2231             :     // In e10s, gChromeInstance hands out quirks to instances, but never
    2232             :     // allocates an instance on its own. Make sure it gets the latest copy
    2233             :     // of quirks once we have them. Also note, with process-per-tab, we may
    2234             :     // have multiple PluginModuleChilds in the same plugin process, so only
    2235             :     // initialize this once in gChromeInstance, which is a singleton.
    2236           0 :     GetChrome()->InitQuirksModes(aMimeType);
    2237           0 :     mQuirks = GetChrome()->mQuirks;
    2238             : 
    2239             : #ifdef XP_WIN
    2240             :     sUser32Intercept.Init("user32.dll");
    2241             :     if ((mQuirks & QUIRK_FLASH_HOOK_GETWINDOWINFO) &&
    2242             :         !sGetWindowInfoPtrStub) {
    2243             :         sUser32Intercept.AddHook("GetWindowInfo", reinterpret_cast<intptr_t>(PMCGetWindowInfoHook),
    2244             :                                  (void**) &sGetWindowInfoPtrStub);
    2245             :     }
    2246             : 
    2247             :     if ((mQuirks & QUIRK_FLASH_HOOK_GETKEYSTATE) &&
    2248             :         !sGetKeyStatePtrStub) {
    2249             :         sUser32Intercept.AddHook("GetKeyState", reinterpret_cast<intptr_t>(PMCGetKeyState),
    2250             :                                  (void**) &sGetKeyStatePtrStub);
    2251             :     }
    2252             : 
    2253             :     if (!sSetCursorPosPtrStub) {
    2254             :         sUser32Intercept.AddHook("SetCursorPos", reinterpret_cast<intptr_t>(PMCSetCursorPos),
    2255             :                                  (void**) &sSetCursorPosPtrStub);
    2256             :     }
    2257             : 
    2258             :     sComDlg32Intercept.Init("comdlg32.dll");
    2259             :     if (!sGetSaveFileNameWPtrStub) {
    2260             :         sComDlg32Intercept.AddHook("GetSaveFileNameW", reinterpret_cast<intptr_t>(PMCGetSaveFileNameW),
    2261             :                                  (void**) &sGetSaveFileNameWPtrStub);
    2262             :     }
    2263             : 
    2264             :     if (!sGetOpenFileNameWPtrStub) {
    2265             :         sComDlg32Intercept.AddHook("GetOpenFileNameW", reinterpret_cast<intptr_t>(PMCGetOpenFileNameW),
    2266             :                                  (void**) &sGetOpenFileNameWPtrStub);
    2267             :     }
    2268             : #endif
    2269             : 
    2270           0 :     return new PluginInstanceChild(&mFunctions, aMimeType, aNames,
    2271           0 :                                    aValues);
    2272             : }
    2273             : 
    2274             : void
    2275           0 : PluginModuleChild::InitQuirksModes(const nsCString& aMimeType)
    2276             : {
    2277           0 :     if (mQuirks != QUIRKS_NOT_INITIALIZED) {
    2278           0 :       return;
    2279             :     }
    2280             : 
    2281           0 :     mQuirks = GetQuirksFromMimeTypeAndFilename(aMimeType, mPluginFilename);
    2282             : }
    2283             : 
    2284             : mozilla::ipc::IPCResult
    2285           0 : PluginModuleChild::AnswerModuleSupportsAsyncRender(bool* aResult)
    2286             : {
    2287             : #if defined(XP_WIN)
    2288             :     *aResult = gChromeInstance->mAsyncRenderSupport;
    2289             :     return IPC_OK();
    2290             : #else
    2291           0 :     NS_NOTREACHED("Shouldn't get here!");
    2292           0 :     return IPC_FAIL_NO_REASON(this);
    2293             : #endif
    2294             : }
    2295             : 
    2296             : mozilla::ipc::IPCResult
    2297           0 : PluginModuleChild::RecvPPluginInstanceConstructor(PPluginInstanceChild* aActor,
    2298             :                                                   const nsCString& aMimeType,
    2299             :                                                   InfallibleTArray<nsCString>&& aNames,
    2300             :                                                   InfallibleTArray<nsCString>&& aValues)
    2301             : {
    2302           0 :     PLUGIN_LOG_DEBUG_METHOD;
    2303           0 :     AssertPluginThread();
    2304             : 
    2305           0 :     NS_ASSERTION(aActor, "Null actor!");
    2306           0 :     return IPC_OK();
    2307             : }
    2308             : 
    2309             : mozilla::ipc::IPCResult
    2310           0 : PluginModuleChild::AnswerSyncNPP_New(PPluginInstanceChild* aActor, NPError* rv)
    2311             : {
    2312           0 :     PLUGIN_LOG_DEBUG_METHOD;
    2313             :     PluginInstanceChild* childInstance =
    2314           0 :         reinterpret_cast<PluginInstanceChild*>(aActor);
    2315           0 :     AssertPluginThread();
    2316           0 :     *rv = childInstance->DoNPP_New();
    2317           0 :     return IPC_OK();
    2318             : }
    2319             : 
    2320             : bool
    2321           0 : PluginModuleChild::DeallocPPluginInstanceChild(PPluginInstanceChild* aActor)
    2322             : {
    2323           0 :     PLUGIN_LOG_DEBUG_METHOD;
    2324           0 :     AssertPluginThread();
    2325             : 
    2326           0 :     delete aActor;
    2327             : 
    2328           0 :     return true;
    2329             : }
    2330             : 
    2331             : NPObject*
    2332           0 : PluginModuleChild::NPN_CreateObject(NPP aNPP, NPClass* aClass)
    2333             : {
    2334           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    2335           0 :     ENSURE_PLUGIN_THREAD(nullptr);
    2336             : 
    2337           0 :     PluginInstanceChild* i = InstCast(aNPP);
    2338           0 :     if (i->mDeletingHash) {
    2339           0 :         NS_ERROR("Plugin used NPP after NPP_Destroy");
    2340           0 :         return nullptr;
    2341             :     }
    2342             : 
    2343             :     NPObject* newObject;
    2344           0 :     if (aClass && aClass->allocate) {
    2345           0 :         newObject = aClass->allocate(aNPP, aClass);
    2346             :     }
    2347             :     else {
    2348           0 :         newObject = reinterpret_cast<NPObject*>(child::_memalloc(sizeof(NPObject)));
    2349             :     }
    2350             : 
    2351           0 :     if (newObject) {
    2352           0 :         newObject->_class = aClass;
    2353           0 :         newObject->referenceCount = 1;
    2354           0 :         NS_LOG_ADDREF(newObject, 1, "NPObject", sizeof(NPObject));
    2355             :     }
    2356             : 
    2357           0 :     PluginScriptableObjectChild::RegisterObject(newObject, i);
    2358             : 
    2359           0 :     return newObject;
    2360             : }
    2361             : 
    2362             : NPObject*
    2363           0 : PluginModuleChild::NPN_RetainObject(NPObject* aNPObj)
    2364             : {
    2365           0 :     AssertPluginThread();
    2366             : 
    2367             : #ifdef NS_BUILD_REFCNT_LOGGING
    2368             :     int32_t refCnt =
    2369             : #endif
    2370           0 :     PR_ATOMIC_INCREMENT((int32_t*)&aNPObj->referenceCount);
    2371           0 :     NS_LOG_ADDREF(aNPObj, refCnt, "NPObject", sizeof(NPObject));
    2372             : 
    2373           0 :     return aNPObj;
    2374             : }
    2375             : 
    2376             : void
    2377           0 : PluginModuleChild::NPN_ReleaseObject(NPObject* aNPObj)
    2378             : {
    2379           0 :     AssertPluginThread();
    2380             : 
    2381           0 :     PluginInstanceChild* instance = PluginScriptableObjectChild::GetInstanceForNPObject(aNPObj);
    2382           0 :     if (!instance) {
    2383           0 :         NS_ERROR("Releasing object not in mObjectMap?");
    2384           0 :         return;
    2385             :     }
    2386             : 
    2387           0 :     DeletingObjectEntry* doe = nullptr;
    2388           0 :     if (instance->mDeletingHash) {
    2389           0 :         doe = instance->mDeletingHash->GetEntry(aNPObj);
    2390           0 :         if (!doe) {
    2391           0 :             NS_ERROR("An object for a destroyed instance isn't in the instance deletion hash");
    2392           0 :             return;
    2393             :         }
    2394           0 :         if (doe->mDeleted)
    2395           0 :             return;
    2396             :     }
    2397             : 
    2398           0 :     int32_t refCnt = PR_ATOMIC_DECREMENT((int32_t*)&aNPObj->referenceCount);
    2399           0 :     NS_LOG_RELEASE(aNPObj, refCnt, "NPObject");
    2400             : 
    2401           0 :     if (refCnt == 0) {
    2402           0 :         DeallocNPObject(aNPObj);
    2403           0 :         if (doe)
    2404           0 :             doe->mDeleted = true;
    2405             :     }
    2406           0 :     return;
    2407             : }
    2408             : 
    2409             : void
    2410           0 : PluginModuleChild::DeallocNPObject(NPObject* aNPObj)
    2411             : {
    2412           0 :     if (aNPObj->_class && aNPObj->_class->deallocate) {
    2413           0 :         aNPObj->_class->deallocate(aNPObj);
    2414             :     } else {
    2415           0 :         child::_memfree(aNPObj);
    2416             :     }
    2417             : 
    2418           0 :     PluginScriptableObjectChild* actor = PluginScriptableObjectChild::GetActorForNPObject(aNPObj);
    2419           0 :     if (actor)
    2420           0 :         actor->NPObjectDestroyed();
    2421             : 
    2422           0 :     PluginScriptableObjectChild::UnregisterObject(aNPObj);
    2423           0 : }
    2424             : 
    2425             : NPIdentifier
    2426           0 : PluginModuleChild::NPN_GetStringIdentifier(const NPUTF8* aName)
    2427             : {
    2428           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    2429           0 :     AssertPluginThread();
    2430             : 
    2431           0 :     if (!aName)
    2432           0 :         return 0;
    2433             : 
    2434           0 :     nsDependentCString name(aName);
    2435           0 :     PluginIdentifier ident(name);
    2436           0 :     PluginScriptableObjectChild::StackIdentifier stackID(ident);
    2437           0 :     stackID.MakePermanent();
    2438           0 :     return stackID.ToNPIdentifier();
    2439             : }
    2440             : 
    2441             : void
    2442           0 : PluginModuleChild::NPN_GetStringIdentifiers(const NPUTF8** aNames,
    2443             :                                             int32_t aNameCount,
    2444             :                                             NPIdentifier* aIdentifiers)
    2445             : {
    2446           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    2447           0 :     AssertPluginThread();
    2448             : 
    2449           0 :     if (!(aNames && aNameCount > 0 && aIdentifiers)) {
    2450           0 :         MOZ_CRASH("Bad input! Headed for a crash!");
    2451             :     }
    2452             : 
    2453           0 :     for (int32_t index = 0; index < aNameCount; ++index) {
    2454           0 :         if (!aNames[index]) {
    2455           0 :             aIdentifiers[index] = 0;
    2456           0 :             continue;
    2457             :         }
    2458           0 :         nsDependentCString name(aNames[index]);
    2459           0 :         PluginIdentifier ident(name);
    2460           0 :         PluginScriptableObjectChild::StackIdentifier stackID(ident);
    2461           0 :         stackID.MakePermanent();
    2462           0 :         aIdentifiers[index] = stackID.ToNPIdentifier();
    2463             :     }
    2464           0 : }
    2465             : 
    2466             : bool
    2467           0 : PluginModuleChild::NPN_IdentifierIsString(NPIdentifier aIdentifier)
    2468             : {
    2469           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    2470             : 
    2471           0 :     PluginScriptableObjectChild::StackIdentifier stack(aIdentifier);
    2472           0 :     return stack.IsString();
    2473             : }
    2474             : 
    2475             : NPIdentifier
    2476           0 : PluginModuleChild::NPN_GetIntIdentifier(int32_t aIntId)
    2477             : {
    2478           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    2479           0 :     AssertPluginThread();
    2480             : 
    2481           0 :     PluginIdentifier ident(aIntId);
    2482           0 :     PluginScriptableObjectChild::StackIdentifier stackID(ident);
    2483           0 :     stackID.MakePermanent();
    2484           0 :     return stackID.ToNPIdentifier();
    2485             : }
    2486             : 
    2487             : NPUTF8*
    2488           0 : PluginModuleChild::NPN_UTF8FromIdentifier(NPIdentifier aIdentifier)
    2489             : {
    2490           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    2491             : 
    2492           0 :     PluginScriptableObjectChild::StackIdentifier stackID(aIdentifier);
    2493           0 :     if (stackID.IsString()) {
    2494           0 :         return ToNewCString(stackID.GetString());
    2495             :     }
    2496           0 :     return nullptr;
    2497             : }
    2498             : 
    2499             : int32_t
    2500           0 : PluginModuleChild::NPN_IntFromIdentifier(NPIdentifier aIdentifier)
    2501             : {
    2502           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    2503             : 
    2504           0 :     PluginScriptableObjectChild::StackIdentifier stackID(aIdentifier);
    2505           0 :     if (!stackID.IsString()) {
    2506           0 :         return stackID.GetInt();
    2507             :     }
    2508           0 :     return INT32_MIN;
    2509             : }
    2510             : 
    2511             : #ifdef OS_WIN
    2512             : void
    2513             : PluginModuleChild::EnteredCall()
    2514             : {
    2515             :     mIncallPumpingStack.AppendElement();
    2516             : }
    2517             : 
    2518             : void
    2519             : PluginModuleChild::ExitedCall()
    2520             : {
    2521             :     NS_ASSERTION(mIncallPumpingStack.Length(), "mismatched entered/exited");
    2522             :     uint32_t len = mIncallPumpingStack.Length();
    2523             :     const IncallFrame& f = mIncallPumpingStack[len - 1];
    2524             :     if (f._spinning)
    2525             :         MessageLoop::current()->SetNestableTasksAllowed(f._savedNestableTasksAllowed);
    2526             : 
    2527             :     mIncallPumpingStack.TruncateLength(len - 1);
    2528             : }
    2529             : 
    2530             : LRESULT CALLBACK
    2531             : PluginModuleChild::CallWindowProcHook(int nCode, WPARAM wParam, LPARAM lParam)
    2532             : {
    2533             :     // Trap and reply to anything we recognize as the source of a
    2534             :     // potential send message deadlock.
    2535             :     if (nCode >= 0 &&
    2536             :         (InSendMessageEx(nullptr)&(ISMEX_REPLIED|ISMEX_SEND)) == ISMEX_SEND) {
    2537             :         CWPSTRUCT* pCwp = reinterpret_cast<CWPSTRUCT*>(lParam);
    2538             :         if (pCwp->message == WM_KILLFOCUS) {
    2539             :             // Fix for flash fullscreen window loosing focus. On single
    2540             :             // core systems, sync killfocus events need to be handled
    2541             :             // after the flash fullscreen window procedure processes this
    2542             :             // message, otherwise fullscreen focus will not work correctly.
    2543             :             wchar_t szClass[26];
    2544             :             if (GetClassNameW(pCwp->hwnd, szClass,
    2545             :                               sizeof(szClass)/sizeof(char16_t)) &&
    2546             :                 !wcscmp(szClass, kFlashFullscreenClass)) {
    2547             :                 gDelayFlashFocusReplyUntilEval = true;
    2548             :             }
    2549             :         }
    2550             :     }
    2551             : 
    2552             :     return CallNextHookEx(nullptr, nCode, wParam, lParam);
    2553             : }
    2554             : 
    2555             : LRESULT CALLBACK
    2556             : PluginModuleChild::NestedInputEventHook(int nCode, WPARAM wParam, LPARAM lParam)
    2557             : {
    2558             :     PluginModuleChild* self = GetChrome();
    2559             :     uint32_t len = self->mIncallPumpingStack.Length();
    2560             :     if (nCode >= 0 && len && !self->mIncallPumpingStack[len - 1]._spinning) {
    2561             :         MessageLoop* loop = MessageLoop::current();
    2562             :         self->SendProcessNativeEventsInInterruptCall();
    2563             :         IncallFrame& f = self->mIncallPumpingStack[len - 1];
    2564             :         f._spinning = true;
    2565             :         f._savedNestableTasksAllowed = loop->NestableTasksAllowed();
    2566             :         loop->SetNestableTasksAllowed(true);
    2567             :         loop->set_os_modal_loop(true);
    2568             :     }
    2569             : 
    2570             :     return CallNextHookEx(nullptr, nCode, wParam, lParam);
    2571             : }
    2572             : 
    2573             : void
    2574             : PluginModuleChild::SetEventHooks()
    2575             : {
    2576             :     NS_ASSERTION(!mNestedEventHook,
    2577             :         "mNestedEventHook already setup in call to SetNestedInputEventHook?");
    2578             :     NS_ASSERTION(!mGlobalCallWndProcHook,
    2579             :         "mGlobalCallWndProcHook already setup in call to CallWindowProcHook?");
    2580             : 
    2581             :     PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
    2582             : 
    2583             :     // WH_MSGFILTER event hook for detecting modal loops in the child.
    2584             :     mNestedEventHook = SetWindowsHookEx(WH_MSGFILTER,
    2585             :                                         NestedInputEventHook,
    2586             :                                         nullptr,
    2587             :                                         GetCurrentThreadId());
    2588             : 
    2589             :     // WH_CALLWNDPROC event hook for trapping sync messages sent from
    2590             :     // parent that can cause deadlocks.
    2591             :     mGlobalCallWndProcHook = SetWindowsHookEx(WH_CALLWNDPROC,
    2592             :                                               CallWindowProcHook,
    2593             :                                               nullptr,
    2594             :                                               GetCurrentThreadId());
    2595             : }
    2596             : 
    2597             : void
    2598             : PluginModuleChild::ResetEventHooks()
    2599             : {
    2600             :     PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
    2601             :     if (mNestedEventHook)
    2602             :         UnhookWindowsHookEx(mNestedEventHook);
    2603             :     mNestedEventHook = nullptr;
    2604             :     if (mGlobalCallWndProcHook)
    2605             :         UnhookWindowsHookEx(mGlobalCallWndProcHook);
    2606             :     mGlobalCallWndProcHook = nullptr;
    2607             : }
    2608             : #endif
    2609             : 
    2610             : mozilla::ipc::IPCResult
    2611           0 : PluginModuleChild::RecvProcessNativeEventsInInterruptCall()
    2612             : {
    2613           0 :     PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
    2614             : #if defined(OS_WIN)
    2615             :     ProcessNativeEventsInInterruptCall();
    2616             :     return IPC_OK();
    2617             : #else
    2618             :     NS_RUNTIMEABORT(
    2619           0 :         "PluginModuleChild::RecvProcessNativeEventsInInterruptCall not implemented!");
    2620           0 :     return IPC_FAIL_NO_REASON(this);
    2621             : #endif
    2622             : }
    2623             : 
    2624             : #ifdef MOZ_WIDGET_COCOA
    2625             : void
    2626             : PluginModuleChild::ProcessNativeEvents() {
    2627             :     CallProcessSomeEvents();
    2628             : }
    2629             : #endif
    2630             : 
    2631             : NPError
    2632           0 : PluginModuleChild::PluginRequiresAudioDeviceChanges(
    2633             :                           PluginInstanceChild* aInstance,
    2634             :                           NPBool aShouldRegister)
    2635             : {
    2636             : #ifdef XP_WIN
    2637             :     // Maintain a set of PluginInstanceChildren that we need to tell when the
    2638             :     // default audio device has changed.
    2639             :     NPError rv = NPERR_NO_ERROR;
    2640             :     if (aShouldRegister) {
    2641             :         if (mAudioNotificationSet.IsEmpty()) {
    2642             :             // We are registering the first plugin.  Notify the PluginModuleParent
    2643             :             // that it needs to start sending us audio device notifications.
    2644             :             if (!CallNPN_SetValue_NPPVpluginRequiresAudioDeviceChanges(
    2645             :                                                       aShouldRegister, &rv)) {
    2646             :                 return NPERR_GENERIC_ERROR;
    2647             :             }
    2648             :         }
    2649             :         if (rv == NPERR_NO_ERROR) {
    2650             :             mAudioNotificationSet.PutEntry(aInstance);
    2651             :         }
    2652             :     }
    2653             :     else if (!mAudioNotificationSet.IsEmpty()) {
    2654             :         mAudioNotificationSet.RemoveEntry(aInstance);
    2655             :         if (mAudioNotificationSet.IsEmpty()) {
    2656             :             // We released the last plugin.  Unregister from the PluginModuleParent.
    2657             :             if (!CallNPN_SetValue_NPPVpluginRequiresAudioDeviceChanges(
    2658             :                                                         aShouldRegister, &rv)) {
    2659             :                 return NPERR_GENERIC_ERROR;
    2660             :             }
    2661             :         }
    2662             :     }
    2663             :     return rv;
    2664             : #else
    2665           0 :     NS_RUNTIMEABORT("PluginRequiresAudioDeviceChanges is not available on this platform.");
    2666           0 :     return NPERR_GENERIC_ERROR;
    2667             : #endif // XP_WIN
    2668             : }
    2669             : 
    2670             : mozilla::ipc::IPCResult
    2671           0 : PluginModuleChild::RecvNPP_SetValue_NPNVaudioDeviceChangeDetails(
    2672             :                               const NPAudioDeviceChangeDetailsIPC& detailsIPC)
    2673             : {
    2674             : #if defined(XP_WIN)
    2675             :     NPAudioDeviceChangeDetails details;
    2676             :     details.flow = detailsIPC.flow;
    2677             :     details.role = detailsIPC.role;
    2678             :     details.defaultDevice = detailsIPC.defaultDevice.c_str();
    2679             :     for (auto iter = mAudioNotificationSet.ConstIter(); !iter.Done(); iter.Next()) {
    2680             :       PluginInstanceChild* pluginInst = iter.Get()->GetKey();
    2681             :       pluginInst->DefaultAudioDeviceChanged(details);
    2682             :     }
    2683             :     return IPC_OK();
    2684             : #else
    2685           0 :     NS_RUNTIMEABORT("NPP_SetValue_NPNVaudioDeviceChangeDetails is a Windows-only message");
    2686           0 :     return IPC_FAIL_NO_REASON(this);
    2687             : #endif
    2688             : }

Generated by: LCOV version 1.13