LCOV - code coverage report
Current view: top level - dom/plugins/ipc - PluginInstanceParent.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 604 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 88 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: 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/DebugOnly.h"
       8             : #include <stdint.h> // for intptr_t
       9             : 
      10             : #include "mozilla/BasicEvents.h"
      11             : #include "mozilla/Preferences.h"
      12             : #include "mozilla/Telemetry.h"
      13             : #include "PluginInstanceParent.h"
      14             : #include "BrowserStreamParent.h"
      15             : #include "PluginBackgroundDestroyer.h"
      16             : #include "PluginModuleParent.h"
      17             : #include "StreamNotifyParent.h"
      18             : #include "npfunctions.h"
      19             : #include "nsAutoPtr.h"
      20             : #include "gfxASurface.h"
      21             : #include "gfxContext.h"
      22             : #include "gfxPlatform.h"
      23             : #include "gfxSharedImageSurface.h"
      24             : #include "nsNetUtil.h"
      25             : #include "nsNPAPIPluginInstance.h"
      26             : #include "nsPluginInstanceOwner.h"
      27             : #include "nsFocusManager.h"
      28             : #include "nsIDOMElement.h"
      29             : #ifdef MOZ_X11
      30             : #include "gfxXlibSurface.h"
      31             : #endif
      32             : #include "gfxUtils.h"
      33             : #include "mozilla/gfx/2D.h"
      34             : #include "Layers.h"
      35             : #include "ImageContainer.h"
      36             : #include "GLContext.h"
      37             : #include "GLContextProvider.h"
      38             : #include "gfxPrefs.h"
      39             : #include "LayersLogging.h"
      40             : #include "mozilla/layers/TextureWrapperImage.h"
      41             : #include "mozilla/layers/TextureClientRecycleAllocator.h"
      42             : #include "mozilla/layers/ImageBridgeChild.h"
      43             : #if defined(XP_WIN)
      44             : # include "mozilla/layers/D3D11ShareHandleImage.h"
      45             : # include "mozilla/gfx/DeviceManagerDx.h"
      46             : # include "mozilla/layers/TextureD3D11.h"
      47             : #endif
      48             : 
      49             : #ifdef XP_MACOSX
      50             : #include "MacIOSurfaceImage.h"
      51             : #endif
      52             : 
      53             : #if defined(OS_WIN)
      54             : #include <windowsx.h>
      55             : #include "gfxWindowsPlatform.h"
      56             : #include "mozilla/plugins/PluginSurfaceParent.h"
      57             : #include "nsClassHashtable.h"
      58             : #include "nsHashKeys.h"
      59             : #include "nsIWidget.h"
      60             : #include "nsPluginNativeWindow.h"
      61             : #include "PluginQuirks.h"
      62             : extern const wchar_t* kFlashFullscreenClass;
      63             : #elif defined(MOZ_WIDGET_GTK)
      64             : #include "mozilla/dom/ContentChild.h"
      65             : #include <gdk/gdk.h>
      66             : #elif defined(XP_MACOSX)
      67             : #include <ApplicationServices/ApplicationServices.h>
      68             : #endif // defined(XP_MACOSX)
      69             : 
      70             : using namespace mozilla::plugins;
      71             : using namespace mozilla::layers;
      72             : using namespace mozilla::gl;
      73             : 
      74             : void
      75           0 : StreamNotifyParent::ActorDestroy(ActorDestroyReason aWhy)
      76             : {
      77             :   // Implement me! Bug 1005162
      78           0 : }
      79             : 
      80             : mozilla::ipc::IPCResult
      81           0 : StreamNotifyParent::RecvRedirectNotifyResponse(const bool& allow)
      82             : {
      83           0 :   PluginInstanceParent* instance = static_cast<PluginInstanceParent*>(Manager());
      84           0 :   instance->mNPNIface->urlredirectresponse(instance->mNPP, this, static_cast<NPBool>(allow));
      85           0 :   return IPC_OK();
      86             : }
      87             : 
      88             : #if defined(XP_WIN)
      89             : namespace mozilla {
      90             : namespace plugins {
      91             : /**
      92             :  * e10s specific, used in cross referencing hwnds with plugin instances so we
      93             :  * can access methods here from PluginWidgetChild.
      94             :  */
      95             : static nsClassHashtable<nsVoidPtrHashKey, PluginInstanceParent>* sPluginInstanceList;
      96             : 
      97             : // static
      98             : PluginInstanceParent*
      99             : PluginInstanceParent::LookupPluginInstanceByID(uintptr_t aId)
     100             : {
     101             :     MOZ_ASSERT(NS_IsMainThread());
     102             :     if (sPluginInstanceList) {
     103             :         return sPluginInstanceList->Get((void*)aId);
     104             :     }
     105             :     return nullptr;
     106             : }
     107             : }
     108             : }
     109             : #endif
     110             : 
     111           0 : PluginInstanceParent::PluginInstanceParent(PluginModuleParent* parent,
     112             :                                            NPP npp,
     113             :                                            const nsCString& aMimeType,
     114           0 :                                            const NPNetscapeFuncs* npniface)
     115             :     : mParent(parent)
     116             :     , mNPP(npp)
     117             :     , mNPNIface(npniface)
     118             :     , mWindowType(NPWindowTypeWindow)
     119             :     , mDrawingModel(kDefaultDrawingModel)
     120             :     , mLastRecordedDrawingModel(-1)
     121           0 :     , mFrameID(0)
     122             : #if defined(OS_WIN)
     123             :     , mPluginHWND(nullptr)
     124             :     , mChildPluginHWND(nullptr)
     125             :     , mChildPluginsParentHWND(nullptr)
     126             :     , mPluginWndProc(nullptr)
     127             :     , mNestedEventState(false)
     128             : #endif // defined(XP_WIN)
     129             : #if defined(XP_MACOSX)
     130             :     , mShWidth(0)
     131             :     , mShHeight(0)
     132             :     , mShColorSpace(nullptr)
     133             : #endif
     134             : {
     135             : #if defined(OS_WIN)
     136             :     if (!sPluginInstanceList) {
     137             :         sPluginInstanceList = new nsClassHashtable<nsVoidPtrHashKey, PluginInstanceParent>();
     138             :     }
     139             : #endif
     140           0 : }
     141             : 
     142           0 : PluginInstanceParent::~PluginInstanceParent()
     143             : {
     144           0 :     if (mNPP)
     145           0 :         mNPP->pdata = nullptr;
     146             : 
     147             : #if defined(OS_WIN)
     148             :     NS_ASSERTION(!(mPluginHWND || mPluginWndProc),
     149             :         "Subclass was not reset correctly before the dtor was reached!");
     150             : #endif
     151             : #if defined(MOZ_WIDGET_COCOA)
     152             :     if (mShWidth != 0 && mShHeight != 0) {
     153             :         DeallocShmem(mShSurface);
     154             :     }
     155             :     if (mShColorSpace)
     156             :         ::CGColorSpaceRelease(mShColorSpace);
     157             : #endif
     158           0 : }
     159             : 
     160             : bool
     161           0 : PluginInstanceParent::InitMetadata(const nsACString& aMimeType,
     162             :                                    const nsACString& aSrcAttribute)
     163             : {
     164           0 :     if (aSrcAttribute.IsEmpty()) {
     165           0 :         return false;
     166             :     }
     167             :     // Ensure that the src attribute is absolute
     168           0 :     RefPtr<nsPluginInstanceOwner> owner = GetOwner();
     169           0 :     if (!owner) {
     170           0 :         return false;
     171             :     }
     172           0 :     nsCOMPtr<nsIURI> baseUri(owner->GetBaseURI());
     173           0 :     return NS_SUCCEEDED(NS_MakeAbsoluteURI(mSrcAttribute, aSrcAttribute, baseUri));
     174             : }
     175             : 
     176             : void
     177           0 : PluginInstanceParent::ActorDestroy(ActorDestroyReason why)
     178             : {
     179             : #if defined(OS_WIN)
     180             :     if (why == AbnormalShutdown) {
     181             :         // If the plugin process crashes, this is the only
     182             :         // chance we get to destroy resources.
     183             :         UnsubclassPluginWindow();
     184             :     }
     185             : #endif
     186           0 :     if (mFrontSurface) {
     187           0 :         mFrontSurface = nullptr;
     188           0 :         if (mImageContainer) {
     189           0 :             mImageContainer->ClearAllImages();
     190             :         }
     191             : #ifdef MOZ_X11
     192           0 :         FinishX(DefaultXDisplay());
     193             : #endif
     194             :     }
     195           0 :     if (IsUsingDirectDrawing() && mImageContainer) {
     196           0 :         mImageContainer->ClearAllImages();
     197             :     }
     198           0 : }
     199             : 
     200             : NPError
     201           0 : PluginInstanceParent::Destroy()
     202             : {
     203             :     NPError retval;
     204             :     {   // Scope for timer
     205             :         Telemetry::AutoTimer<Telemetry::BLOCKED_ON_PLUGIN_INSTANCE_DESTROY_MS>
     206           0 :             timer(Module()->GetHistogramKey());
     207           0 :         if (!CallNPP_Destroy(&retval)) {
     208           0 :             retval = NPERR_GENERIC_ERROR;
     209             :         }
     210             :     }
     211             : 
     212             : #if defined(OS_WIN)
     213             :     UnsubclassPluginWindow();
     214             : #endif
     215             : 
     216           0 :     return retval;
     217             : }
     218             : 
     219             : bool
     220           0 : PluginInstanceParent::IsUsingDirectDrawing()
     221             : {
     222           0 :     return IsDrawingModelDirect(mDrawingModel);
     223             : }
     224             : 
     225             : PBrowserStreamParent*
     226           0 : PluginInstanceParent::AllocPBrowserStreamParent(const nsCString& url,
     227             :                                                 const uint32_t& length,
     228             :                                                 const uint32_t& lastmodified,
     229             :                                                 PStreamNotifyParent* notifyData,
     230             :                                                 const nsCString& headers)
     231             : {
     232           0 :     MOZ_CRASH("Not reachable");
     233             :     return nullptr;
     234             : }
     235             : 
     236             : bool
     237           0 : PluginInstanceParent::DeallocPBrowserStreamParent(PBrowserStreamParent* stream)
     238             : {
     239           0 :     delete stream;
     240           0 :     return true;
     241             : }
     242             : 
     243             : 
     244             : mozilla::ipc::IPCResult
     245           0 : PluginInstanceParent::AnswerNPN_GetValue_NPNVnetscapeWindow(NativeWindowHandle* value,
     246             :                                                             NPError* result)
     247             : {
     248             : #ifdef XP_WIN
     249             :     HWND id;
     250             : #elif defined(MOZ_X11)
     251             :     XID id;
     252             : #elif defined(XP_DARWIN)
     253             :     intptr_t id;
     254             : #elif defined(ANDROID)
     255             :     // TODO: Need Android impl
     256             :     int id;
     257             : #else
     258             : #warning Implement me
     259             : #endif
     260             : 
     261           0 :     *result = mNPNIface->getvalue(mNPP, NPNVnetscapeWindow, &id);
     262           0 :     *value = id;
     263           0 :     return IPC_OK();
     264             : }
     265             : 
     266             : bool
     267           0 : PluginInstanceParent::InternalGetValueForNPObject(
     268             :                                          NPNVariable aVariable,
     269             :                                          PPluginScriptableObjectParent** aValue,
     270             :                                          NPError* aResult)
     271             : {
     272             :     NPObject* npobject;
     273           0 :     NPError result = mNPNIface->getvalue(mNPP, aVariable, (void*)&npobject);
     274           0 :     if (result == NPERR_NO_ERROR) {
     275           0 :         NS_ASSERTION(npobject, "Shouldn't return null and NPERR_NO_ERROR!");
     276             : 
     277           0 :         PluginScriptableObjectParent* actor = GetActorForNPObject(npobject);
     278           0 :         mNPNIface->releaseobject(npobject);
     279           0 :         if (actor) {
     280           0 :             *aValue = actor;
     281           0 :             *aResult = NPERR_NO_ERROR;
     282           0 :             return true;
     283             :         }
     284             : 
     285           0 :         NS_ERROR("Failed to get actor!");
     286           0 :         result = NPERR_GENERIC_ERROR;
     287             :     }
     288             : 
     289           0 :     *aValue = nullptr;
     290           0 :     *aResult = result;
     291           0 :     return true;
     292             : }
     293             : 
     294             : mozilla::ipc::IPCResult
     295           0 : PluginInstanceParent::AnswerNPN_GetValue_NPNVWindowNPObject(
     296             :                                          PPluginScriptableObjectParent** aValue,
     297             :                                          NPError* aResult)
     298             : {
     299           0 :     if (!InternalGetValueForNPObject(NPNVWindowNPObject, aValue, aResult)) {
     300           0 :       return IPC_FAIL_NO_REASON(this);
     301             :     }
     302           0 :     return IPC_OK();
     303             : }
     304             : 
     305             : mozilla::ipc::IPCResult
     306           0 : PluginInstanceParent::AnswerNPN_GetValue_NPNVPluginElementNPObject(
     307             :                                          PPluginScriptableObjectParent** aValue,
     308             :                                          NPError* aResult)
     309             : {
     310           0 :     if (!InternalGetValueForNPObject(NPNVPluginElementNPObject, aValue,
     311             :                                      aResult)) {
     312           0 :       return IPC_FAIL_NO_REASON(this);
     313             :     }
     314           0 :     return IPC_OK();
     315             : }
     316             : 
     317             : mozilla::ipc::IPCResult
     318           0 : PluginInstanceParent::AnswerNPN_GetValue_NPNVprivateModeBool(bool* value,
     319             :                                                              NPError* result)
     320             : {
     321             :     NPBool v;
     322           0 :     *result = mNPNIface->getvalue(mNPP, NPNVprivateModeBool, &v);
     323           0 :     *value = v;
     324           0 :     return IPC_OK();
     325             : }
     326             : 
     327             : mozilla::ipc::IPCResult
     328           0 : PluginInstanceParent::AnswerNPN_GetValue_DrawingModelSupport(const NPNVariable& model, bool* value)
     329             : {
     330           0 :     *value = false;
     331           0 :     return IPC_OK();
     332             : }
     333             : 
     334             : mozilla::ipc::IPCResult
     335           0 : PluginInstanceParent::AnswerNPN_GetValue_NPNVdocumentOrigin(nsCString* value,
     336             :                                                             NPError* result)
     337             : {
     338           0 :     void *v = nullptr;
     339           0 :     *result = mNPNIface->getvalue(mNPP, NPNVdocumentOrigin, &v);
     340           0 :     if (*result == NPERR_NO_ERROR && v) {
     341           0 :         value->Adopt(static_cast<char*>(v));
     342             :     }
     343           0 :     return IPC_OK();
     344             : }
     345             : 
     346             : static inline bool
     347           0 : AllowDirectBitmapSurfaceDrawing()
     348             : {
     349           0 :     if (!gfxPrefs::PluginAsyncDrawingEnabled()) {
     350           0 :         return false;
     351             :     }
     352           0 :     return gfxPlatform::GetPlatform()->SupportsPluginDirectBitmapDrawing();
     353             : }
     354             : 
     355             : static inline bool
     356           0 : AllowDirectDXGISurfaceDrawing()
     357             : {
     358           0 :     if (!gfxPrefs::PluginAsyncDrawingEnabled()) {
     359           0 :         return false;
     360             :     }
     361             : #if defined(XP_WIN)
     362             :     return gfxWindowsPlatform::GetPlatform()->SupportsPluginDirectDXGIDrawing();
     363             : #else
     364           0 :     return false;
     365             : #endif
     366             : }
     367             : 
     368             : mozilla::ipc::IPCResult
     369           0 : PluginInstanceParent::AnswerNPN_GetValue_SupportsAsyncBitmapSurface(bool* value)
     370             : {
     371           0 :     *value = AllowDirectBitmapSurfaceDrawing();
     372           0 :     return IPC_OK();
     373             : }
     374             : 
     375             : mozilla::ipc::IPCResult
     376           0 : PluginInstanceParent::AnswerNPN_GetValue_SupportsAsyncDXGISurface(bool* value)
     377             : {
     378           0 :     *value = AllowDirectDXGISurfaceDrawing();
     379           0 :     return IPC_OK();
     380             : }
     381             : 
     382             : mozilla::ipc::IPCResult
     383           0 : PluginInstanceParent::AnswerNPN_GetValue_PreferredDXGIAdapter(DxgiAdapterDesc* aOutDesc)
     384             : {
     385           0 :     PodZero(aOutDesc);
     386             : #ifdef XP_WIN
     387             :     if (!AllowDirectDXGISurfaceDrawing()) {
     388             :         return IPC_FAIL_NO_REASON(this);
     389             :     }
     390             : 
     391             :     RefPtr<ID3D11Device> device = DeviceManagerDx::Get()->GetContentDevice();
     392             :     if (!device) {
     393             :         return IPC_FAIL_NO_REASON(this);
     394             :     }
     395             : 
     396             :     RefPtr<IDXGIDevice> dxgi;
     397             :     if (FAILED(device->QueryInterface(__uuidof(IDXGIDevice), getter_AddRefs(dxgi))) || !dxgi) {
     398             :         return IPC_FAIL_NO_REASON(this);
     399             :     }
     400             :     RefPtr<IDXGIAdapter> adapter;
     401             :     if (FAILED(dxgi->GetAdapter(getter_AddRefs(adapter))) || !adapter) {
     402             :         return IPC_FAIL_NO_REASON(this);
     403             :     }
     404             : 
     405             :     DXGI_ADAPTER_DESC desc;
     406             :     if (FAILED(adapter->GetDesc(&desc))) {
     407             :         return IPC_FAIL_NO_REASON(this);
     408             :     }
     409             : 
     410             :     *aOutDesc = DxgiAdapterDesc::From(desc);
     411             : #endif
     412           0 :     return IPC_OK();
     413             : }
     414             : 
     415             : mozilla::ipc::IPCResult
     416           0 : PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginWindow(
     417             :     const bool& windowed, NPError* result)
     418             : {
     419             :     // Yes, we are passing a boolean as a void*.  We have to cast to intptr_t
     420             :     // first to avoid gcc warnings about casting to a pointer from a
     421             :     // non-pointer-sized integer.
     422           0 :     *result = mNPNIface->setvalue(mNPP, NPPVpluginWindowBool,
     423           0 :                                   (void*)(intptr_t)windowed);
     424           0 :     return IPC_OK();
     425             : }
     426             : 
     427             : mozilla::ipc::IPCResult
     428           0 : PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginTransparent(
     429             :     const bool& transparent, NPError* result)
     430             : {
     431           0 :     *result = mNPNIface->setvalue(mNPP, NPPVpluginTransparentBool,
     432           0 :                                   (void*)(intptr_t)transparent);
     433           0 :     return IPC_OK();
     434             : }
     435             : 
     436             : mozilla::ipc::IPCResult
     437           0 : PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginUsesDOMForCursor(
     438             :     const bool& useDOMForCursor, NPError* result)
     439             : {
     440           0 :     *result = mNPNIface->setvalue(mNPP, NPPVpluginUsesDOMForCursorBool,
     441           0 :                                   (void*)(intptr_t)useDOMForCursor);
     442           0 :     return IPC_OK();
     443             : }
     444             : 
     445             : mozilla::ipc::IPCResult
     446           0 : PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginDrawingModel(
     447             :     const int& drawingModel, NPError* result)
     448             : {
     449           0 :     bool allowed = false;
     450             : 
     451           0 :     switch (drawingModel) {
     452             : #if defined(XP_MACOSX)
     453             :         case NPDrawingModelCoreAnimation:
     454             :         case NPDrawingModelInvalidatingCoreAnimation:
     455             :         case NPDrawingModelOpenGL:
     456             :         case NPDrawingModelCoreGraphics:
     457             :             allowed = true;
     458             :             break;
     459             : #elif defined(XP_WIN)
     460             :         case NPDrawingModelSyncWin:
     461             :             allowed = true;
     462             :             break;
     463             :         case NPDrawingModelAsyncWindowsDXGISurface:
     464             :             allowed = AllowDirectDXGISurfaceDrawing();
     465             :             break;
     466             : #elif defined(MOZ_X11)
     467             :         case NPDrawingModelSyncX:
     468           0 :             allowed = true;
     469           0 :             break;
     470             : #endif
     471             :         case NPDrawingModelAsyncBitmapSurface:
     472           0 :             allowed = AllowDirectBitmapSurfaceDrawing();
     473           0 :             break;
     474             :         default:
     475           0 :             allowed = false;
     476           0 :             break;
     477             :     }
     478             : 
     479           0 :     if (!allowed) {
     480           0 :         *result = NPERR_GENERIC_ERROR;
     481           0 :         return IPC_OK();
     482             :     }
     483             : 
     484           0 :     mDrawingModel = drawingModel;
     485             : 
     486           0 :     int requestModel = drawingModel;
     487             : 
     488             : #ifdef XP_MACOSX
     489             :     if (drawingModel == NPDrawingModelCoreAnimation ||
     490             :         drawingModel == NPDrawingModelInvalidatingCoreAnimation) {
     491             :         // We need to request CoreGraphics otherwise
     492             :         // the nsPluginFrame will try to draw a CALayer
     493             :         // that can not be shared across process.
     494             :         requestModel = NPDrawingModelCoreGraphics;
     495             :     }
     496             : #endif
     497             : 
     498           0 :     *result = mNPNIface->setvalue(mNPP, NPPVpluginDrawingModel,
     499           0 :                                   (void*)(intptr_t)requestModel);
     500             : 
     501           0 :     return IPC_OK();
     502             : }
     503             : 
     504             : mozilla::ipc::IPCResult
     505           0 : PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginEventModel(
     506             :     const int& eventModel, NPError* result)
     507             : {
     508             : #ifdef XP_MACOSX
     509             :     *result = mNPNIface->setvalue(mNPP, NPPVpluginEventModel,
     510             :                                   (void*)(intptr_t)eventModel);
     511             :     return IPC_OK();
     512             : #else
     513           0 :     *result = NPERR_GENERIC_ERROR;
     514           0 :     return IPC_OK();
     515             : #endif
     516             : }
     517             : 
     518             : mozilla::ipc::IPCResult
     519           0 : PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginIsPlayingAudio(
     520             :     const bool& isAudioPlaying, NPError* result)
     521             : {
     522           0 :     *result = mNPNIface->setvalue(mNPP, NPPVpluginIsPlayingAudio,
     523           0 :                                   (void*)(intptr_t)isAudioPlaying);
     524           0 :     return IPC_OK();
     525             : }
     526             : 
     527             : mozilla::ipc::IPCResult
     528           0 : PluginInstanceParent::AnswerNPN_GetURL(const nsCString& url,
     529             :                                        const nsCString& target,
     530             :                                        NPError* result)
     531             : {
     532           0 :     *result = mNPNIface->geturl(mNPP,
     533             :                                 NullableStringGet(url),
     534             :                                 NullableStringGet(target));
     535           0 :     return IPC_OK();
     536             : }
     537             : 
     538             : mozilla::ipc::IPCResult
     539           0 : PluginInstanceParent::AnswerNPN_PostURL(const nsCString& url,
     540             :                                         const nsCString& target,
     541             :                                         const nsCString& buffer,
     542             :                                         const bool& file,
     543             :                                         NPError* result)
     544             : {
     545           0 :     *result = mNPNIface->posturl(mNPP, url.get(), NullableStringGet(target),
     546           0 :                                  buffer.Length(), buffer.get(), file);
     547           0 :     return IPC_OK();
     548             : }
     549             : 
     550             : PStreamNotifyParent*
     551           0 : PluginInstanceParent::AllocPStreamNotifyParent(const nsCString& url,
     552             :                                                const nsCString& target,
     553             :                                                const bool& post,
     554             :                                                const nsCString& buffer,
     555             :                                                const bool& file,
     556             :                                                NPError* result)
     557             : {
     558           0 :     return new StreamNotifyParent();
     559             : }
     560             : 
     561             : mozilla::ipc::IPCResult
     562           0 : PluginInstanceParent::AnswerPStreamNotifyConstructor(PStreamNotifyParent* actor,
     563             :                                                      const nsCString& url,
     564             :                                                      const nsCString& target,
     565             :                                                      const bool& post,
     566             :                                                      const nsCString& buffer,
     567             :                                                      const bool& file,
     568             :                                                      NPError* result)
     569             : {
     570           0 :     bool streamDestroyed = false;
     571             :     static_cast<StreamNotifyParent*>(actor)->
     572           0 :         SetDestructionFlag(&streamDestroyed);
     573             : 
     574           0 :     if (!post) {
     575           0 :         *result = mNPNIface->geturlnotify(mNPP,
     576             :                                           NullableStringGet(url),
     577             :                                           NullableStringGet(target),
     578             :                                           actor);
     579             :     }
     580             :     else {
     581           0 :         *result = mNPNIface->posturlnotify(mNPP,
     582             :                                            NullableStringGet(url),
     583             :                                            NullableStringGet(target),
     584             :                                            buffer.Length(),
     585             :                                            NullableStringGet(buffer),
     586           0 :                                            file, actor);
     587             :     }
     588             : 
     589           0 :     if (streamDestroyed) {
     590             :         // If the stream was destroyed, we must return an error code in the
     591             :         // constructor.
     592           0 :         *result = NPERR_GENERIC_ERROR;
     593             :     }
     594             :     else {
     595           0 :         static_cast<StreamNotifyParent*>(actor)->ClearDestructionFlag();
     596           0 :         if (*result != NPERR_NO_ERROR) {
     597           0 :             if (!PStreamNotifyParent::Send__delete__(actor,
     598             :                                                      NPERR_GENERIC_ERROR)) {
     599           0 :               return IPC_FAIL_NO_REASON(this);
     600             :             }
     601           0 :             return IPC_OK();
     602             :         }
     603             :     }
     604             : 
     605           0 :     return IPC_OK();
     606             : }
     607             : 
     608             : bool
     609           0 : PluginInstanceParent::DeallocPStreamNotifyParent(PStreamNotifyParent* notifyData)
     610             : {
     611           0 :     delete notifyData;
     612           0 :     return true;
     613             : }
     614             : 
     615             : mozilla::ipc::IPCResult
     616           0 : PluginInstanceParent::RecvNPN_InvalidateRect(const NPRect& rect)
     617             : {
     618           0 :     mNPNIface->invalidaterect(mNPP, const_cast<NPRect*>(&rect));
     619           0 :     return IPC_OK();
     620             : }
     621             : 
     622             : static inline NPRect
     623             : IntRectToNPRect(const gfx::IntRect& rect)
     624             : {
     625             :     NPRect r;
     626             :     r.left = rect.x;
     627             :     r.top = rect.y;
     628             :     r.right = rect.x + rect.width;
     629             :     r.bottom = rect.y + rect.height;
     630             :     return r;
     631             : }
     632             : 
     633             : mozilla::ipc::IPCResult
     634           0 : PluginInstanceParent::RecvRevokeCurrentDirectSurface()
     635             : {
     636           0 :     ImageContainer *container = GetImageContainer();
     637           0 :     if (!container) {
     638           0 :         return IPC_OK();
     639             :     }
     640             : 
     641           0 :     container->ClearAllImages();
     642             : 
     643           0 :     PLUGIN_LOG_DEBUG(("   (RecvRevokeCurrentDirectSurface)"));
     644           0 :     return IPC_OK();
     645             : }
     646             : 
     647             : mozilla::ipc::IPCResult
     648           0 : PluginInstanceParent::RecvInitDXGISurface(const gfx::SurfaceFormat& format,
     649             :                                            const gfx::IntSize& size,
     650             :                                            WindowsHandle* outHandle,
     651             :                                            NPError* outError)
     652             : {
     653           0 :     *outHandle = 0;
     654           0 :     *outError = NPERR_GENERIC_ERROR;
     655             : 
     656             : #if defined(XP_WIN)
     657             :     if (format != SurfaceFormat::B8G8R8A8 && format != SurfaceFormat::B8G8R8X8) {
     658             :         *outError = NPERR_INVALID_PARAM;
     659             :         return IPC_OK();
     660             :     }
     661             :     if (size.width <= 0 || size.height <= 0) {
     662             :         *outError = NPERR_INVALID_PARAM;
     663             :         return IPC_OK();
     664             :     }
     665             : 
     666             :     ImageContainer *container = GetImageContainer();
     667             :     if (!container) {
     668             :         return IPC_OK();
     669             :     }
     670             : 
     671             :     RefPtr<ImageBridgeChild> forwarder = ImageBridgeChild::GetSingleton();
     672             :     if (!forwarder) {
     673             :         return IPC_OK();
     674             :     }
     675             : 
     676             :     RefPtr<ID3D11Device> d3d11 = DeviceManagerDx::Get()->GetContentDevice();
     677             :     if (!d3d11) {
     678             :         return IPC_OK();
     679             :     }
     680             : 
     681             :     // Create the texture we'll give to the plugin process.
     682             :     HANDLE sharedHandle = 0;
     683             :     RefPtr<ID3D11Texture2D> back;
     684             :     {
     685             :         CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, size.width, size.height, 1, 1);
     686             :         desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
     687             :         desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
     688             :         if (FAILED(d3d11->CreateTexture2D(&desc, nullptr, getter_AddRefs(back))) || !back) {
     689             :             return IPC_OK();
     690             :         }
     691             : 
     692             :         RefPtr<IDXGIResource> resource;
     693             :         if (FAILED(back->QueryInterface(IID_IDXGIResource, getter_AddRefs(resource))) || !resource) {
     694             :             return IPC_OK();
     695             :         }
     696             :         if (FAILED(resource->GetSharedHandle(&sharedHandle) || !sharedHandle)) {
     697             :             return IPC_OK();
     698             :         }
     699             :     }
     700             : 
     701             :     RefPtr<D3D11SurfaceHolder> holder = new D3D11SurfaceHolder(back, format, size);
     702             :     mD3D11Surfaces.Put(reinterpret_cast<void*>(sharedHandle), holder);
     703             : 
     704             :     *outHandle = reinterpret_cast<uintptr_t>(sharedHandle);
     705             :     *outError = NPERR_NO_ERROR;
     706             : #endif
     707           0 :     return IPC_OK();
     708             : }
     709             : 
     710             : mozilla::ipc::IPCResult
     711           0 : PluginInstanceParent::RecvFinalizeDXGISurface(const WindowsHandle& handle)
     712             : {
     713             : #if defined(XP_WIN)
     714             :     mD3D11Surfaces.Remove(reinterpret_cast<void*>(handle));
     715             : #endif
     716           0 :     return IPC_OK();
     717             : }
     718             : 
     719             : mozilla::ipc::IPCResult
     720           0 : PluginInstanceParent::RecvShowDirectBitmap(Shmem&& buffer,
     721             :                                            const SurfaceFormat& format,
     722             :                                            const uint32_t& stride,
     723             :                                            const IntSize& size,
     724             :                                            const IntRect& dirty)
     725             : {
     726             :     // Validate format.
     727           0 :     if (format != SurfaceFormat::B8G8R8A8 && format != SurfaceFormat::B8G8R8X8) {
     728           0 :         MOZ_ASSERT_UNREACHABLE("bad format type");
     729             :         return IPC_FAIL_NO_REASON(this);
     730             :     }
     731           0 :     if (size.width <= 0 || size.height <= 0) {
     732           0 :         MOZ_ASSERT_UNREACHABLE("bad image size");
     733             :         return IPC_FAIL_NO_REASON(this);
     734             :     }
     735           0 :     if (mDrawingModel != NPDrawingModelAsyncBitmapSurface) {
     736           0 :         MOZ_ASSERT_UNREACHABLE("plugin did not set a bitmap drawing model");
     737             :         return IPC_FAIL_NO_REASON(this);
     738             :     }
     739             : 
     740             :     // Validate buffer and size.
     741           0 :     CheckedInt<uint32_t> nbytes = CheckedInt<uint32_t>(uint32_t(size.height)) * stride;
     742           0 :     if (!nbytes.isValid() || nbytes.value() != buffer.Size<uint8_t>()) {
     743           0 :         MOZ_ASSERT_UNREACHABLE("bad shmem size");
     744             :         return IPC_FAIL_NO_REASON(this);
     745             :     }
     746             : 
     747           0 :     ImageContainer* container = GetImageContainer();
     748           0 :     if (!container) {
     749           0 :         return IPC_FAIL_NO_REASON(this);
     750             :     }
     751             : 
     752             :     RefPtr<gfx::DataSourceSurface> source =
     753           0 :         gfx::Factory::CreateWrappingDataSourceSurface(buffer.get<uint8_t>(), stride, size, format);
     754           0 :     if (!source) {
     755           0 :         return IPC_FAIL_NO_REASON(this);
     756             :     }
     757             : 
     758             :     // Allocate a texture for the compositor.
     759           0 :     RefPtr<TextureClientRecycleAllocator> allocator = mParent->EnsureTextureAllocatorForDirectBitmap();
     760           0 :     RefPtr<TextureClient> texture = allocator->CreateOrRecycle(
     761             :         format, size, BackendSelector::Content,
     762             :         TextureFlags::NO_FLAGS,
     763           0 :         TextureAllocationFlags(ALLOC_FOR_OUT_OF_BAND_CONTENT | ALLOC_UPDATE_FROM_SURFACE));
     764           0 :     if (!texture) {
     765           0 :         NS_WARNING("Could not allocate a TextureClient for plugin!");
     766           0 :         return IPC_FAIL_NO_REASON(this);
     767             :     }
     768             : 
     769             :     // Upload the plugin buffer.
     770             :     {
     771           0 :         TextureClientAutoLock autoLock(texture, OpenMode::OPEN_WRITE_ONLY);
     772           0 :         if (!autoLock.Succeeded()) {
     773           0 :             return IPC_FAIL_NO_REASON(this);
     774             :         }
     775           0 :         texture->UpdateFromSurface(source);
     776             :     }
     777             : 
     778             :     // Wrap the texture in an image and ship it off.
     779             :     RefPtr<TextureWrapperImage> image =
     780           0 :         new TextureWrapperImage(texture, gfx::IntRect(gfx::IntPoint(0, 0), size));
     781           0 :     SetCurrentImage(image);
     782             : 
     783           0 :     PLUGIN_LOG_DEBUG(("   (RecvShowDirectBitmap received shmem=%p stride=%d size=%s dirty=%s)",
     784             :         buffer.get<unsigned char>(), stride, Stringify(size).c_str(), Stringify(dirty).c_str()));
     785           0 :     return IPC_OK();
     786             : }
     787             : 
     788             : void
     789           0 : PluginInstanceParent::SetCurrentImage(Image* aImage)
     790             : {
     791           0 :     MOZ_ASSERT(IsUsingDirectDrawing());
     792           0 :     ImageContainer::NonOwningImage holder(aImage);
     793           0 :     holder.mFrameID = ++mFrameID;
     794             : 
     795           0 :     AutoTArray<ImageContainer::NonOwningImage,1> imageList;
     796           0 :     imageList.AppendElement(holder);
     797           0 :     mImageContainer->SetCurrentImages(imageList);
     798             : 
     799             :     // Invalidate our area in the page so the image gets flushed.
     800           0 :     gfx::IntRect rect = aImage->GetPictureRect();
     801           0 :     NPRect nprect = {uint16_t(rect.x), uint16_t(rect.y), uint16_t(rect.width), uint16_t(rect.height)};
     802           0 :     RecvNPN_InvalidateRect(nprect);
     803             : 
     804           0 :     RecordDrawingModel();
     805           0 : }
     806             : 
     807             : mozilla::ipc::IPCResult
     808           0 : PluginInstanceParent::RecvShowDirectDXGISurface(const WindowsHandle& handle,
     809             :                                                  const gfx::IntRect& dirty)
     810             : {
     811             : #if defined(XP_WIN)
     812             :     RefPtr<D3D11SurfaceHolder> surface;
     813             :     if (!mD3D11Surfaces.Get(reinterpret_cast<void*>(handle), getter_AddRefs(surface))) {
     814             :         return IPC_FAIL_NO_REASON(this);
     815             :     }
     816             :     if (!surface->IsValid()) {
     817             :         return IPC_FAIL_NO_REASON(this);
     818             :     }
     819             : 
     820             :     ImageContainer* container = GetImageContainer();
     821             :     if (!container) {
     822             :         return IPC_FAIL_NO_REASON(this);
     823             :     }
     824             : 
     825             :     RefPtr<TextureClientRecycleAllocator> allocator = mParent->EnsureTextureAllocatorForDXGISurface();
     826             :     RefPtr<TextureClient> texture = allocator->CreateOrRecycle(
     827             :         surface->GetFormat(), surface->GetSize(),
     828             :         BackendSelector::Content,
     829             :         TextureFlags::NO_FLAGS,
     830             :         ALLOC_FOR_OUT_OF_BAND_CONTENT);
     831             :     if (!texture) {
     832             :         NS_WARNING("Could not allocate a TextureClient for plugin!");
     833             :         return IPC_FAIL_NO_REASON(this);
     834             :     }
     835             : 
     836             :     surface->CopyToTextureClient(texture);
     837             : 
     838             :     gfx::IntSize size(surface->GetSize());
     839             :     gfx::IntRect pictureRect(gfx::IntPoint(0, 0), size);
     840             : 
     841             :     // Wrap the texture in an image and ship it off.
     842             :     RefPtr<TextureWrapperImage> image = new TextureWrapperImage(texture, pictureRect);
     843             :     SetCurrentImage(image);
     844             : 
     845             :     PLUGIN_LOG_DEBUG(("   (RecvShowDirect3D10Surface received handle=%p rect=%s)",
     846             :         reinterpret_cast<void*>(handle), Stringify(dirty).c_str()));
     847             :     return IPC_OK();
     848             : #else
     849           0 :     return IPC_FAIL_NO_REASON(this);
     850             : #endif
     851             : }
     852             : 
     853             : mozilla::ipc::IPCResult
     854           0 : PluginInstanceParent::RecvShow(const NPRect& updatedRect,
     855             :                                const SurfaceDescriptor& newSurface,
     856             :                                SurfaceDescriptor* prevSurface)
     857             : {
     858           0 :     PLUGIN_LOG_DEBUG(
     859             :         ("[InstanceParent][%p] RecvShow for <x=%d,y=%d, w=%d,h=%d>",
     860             :          this, updatedRect.left, updatedRect.top,
     861             :          updatedRect.right - updatedRect.left,
     862             :          updatedRect.bottom - updatedRect.top));
     863             : 
     864           0 :     MOZ_ASSERT(!IsUsingDirectDrawing());
     865             : 
     866             :     // XXXjwatt rewrite to use Moz2D
     867           0 :     RefPtr<gfxASurface> surface;
     868           0 :     if (newSurface.type() == SurfaceDescriptor::TShmem) {
     869           0 :         if (!newSurface.get_Shmem().IsReadable()) {
     870           0 :             NS_WARNING("back surface not readable");
     871           0 :             return IPC_FAIL_NO_REASON(this);
     872             :         }
     873           0 :         surface = gfxSharedImageSurface::Open(newSurface.get_Shmem());
     874             :     }
     875             : #ifdef XP_MACOSX
     876             :     else if (newSurface.type() == SurfaceDescriptor::TIOSurfaceDescriptor) {
     877             :         IOSurfaceDescriptor iodesc = newSurface.get_IOSurfaceDescriptor();
     878             : 
     879             :         RefPtr<MacIOSurface> newIOSurface =
     880             :           MacIOSurface::LookupSurface(iodesc.surfaceId(),
     881             :                                       iodesc.contentsScaleFactor());
     882             : 
     883             :         if (!newIOSurface) {
     884             :             NS_WARNING("Got bad IOSurfaceDescriptor in RecvShow");
     885             :             return IPC_FAIL_NO_REASON(this);
     886             :         }
     887             : 
     888             :         if (mFrontIOSurface)
     889             :             *prevSurface = IOSurfaceDescriptor(mFrontIOSurface->GetIOSurfaceID(),
     890             :                                                mFrontIOSurface->GetContentsScaleFactor());
     891             :         else
     892             :             *prevSurface = null_t();
     893             : 
     894             :         mFrontIOSurface = newIOSurface;
     895             : 
     896             :         RecvNPN_InvalidateRect(updatedRect);
     897             : 
     898             :         PLUGIN_LOG_DEBUG(("   (RecvShow invalidated for surface %p)",
     899             :                           mFrontSurface.get()));
     900             : 
     901             :         return IPC_OK();
     902             :     }
     903             : #endif
     904             : #ifdef MOZ_X11
     905           0 :     else if (newSurface.type() == SurfaceDescriptor::TSurfaceDescriptorX11) {
     906           0 :         surface = newSurface.get_SurfaceDescriptorX11().OpenForeign();
     907             :     }
     908             : #endif
     909             : #ifdef XP_WIN
     910             :     else if (newSurface.type() == SurfaceDescriptor::TPPluginSurfaceParent) {
     911             :         PluginSurfaceParent* s =
     912             :             static_cast<PluginSurfaceParent*>(newSurface.get_PPluginSurfaceParent());
     913             :         surface = s->Surface();
     914             :     }
     915             : #endif
     916             : 
     917           0 :     if (mFrontSurface) {
     918             :         // This is the "old front buffer" we're about to hand back to
     919             :         // the plugin.  We might still have drawing operations
     920             :         // referencing it.
     921             : #ifdef MOZ_X11
     922           0 :         if (mFrontSurface->GetType() == gfxSurfaceType::Xlib) {
     923             :             // Finish with the surface and XSync here to ensure the server has
     924             :             // finished operations on the surface before the plugin starts
     925             :             // scribbling on it again, or worse, destroys it.
     926           0 :             mFrontSurface->Finish();
     927           0 :             FinishX(DefaultXDisplay());
     928             :         } else
     929             : #endif
     930             :         {
     931           0 :             mFrontSurface->Flush();
     932             :         }
     933             :     }
     934             : 
     935           0 :     if (mFrontSurface && gfxSharedImageSurface::IsSharedImage(mFrontSurface))
     936           0 :         *prevSurface = static_cast<gfxSharedImageSurface*>(mFrontSurface.get())->GetShmem();
     937             :     else
     938           0 :         *prevSurface = null_t();
     939             : 
     940           0 :     if (surface) {
     941             :         // Notify the cairo backend that this surface has changed behind
     942             :         // its back.
     943           0 :         gfxRect ur(updatedRect.left, updatedRect.top,
     944           0 :                    updatedRect.right - updatedRect.left,
     945           0 :                    updatedRect.bottom - updatedRect.top);
     946           0 :         surface->MarkDirty(ur);
     947             : 
     948           0 :         bool isPlugin = true;
     949             :         RefPtr<gfx::SourceSurface> sourceSurface =
     950           0 :             gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr, surface, isPlugin);
     951           0 :         RefPtr<SourceSurfaceImage> image = new SourceSurfaceImage(surface->GetSize(), sourceSurface);
     952             : 
     953           0 :         AutoTArray<ImageContainer::NonOwningImage,1> imageList;
     954             :         imageList.AppendElement(
     955           0 :             ImageContainer::NonOwningImage(image));
     956             : 
     957           0 :         ImageContainer *container = GetImageContainer();
     958           0 :         container->SetCurrentImages(imageList);
     959             :     }
     960           0 :     else if (mImageContainer) {
     961           0 :         mImageContainer->ClearAllImages();
     962             :     }
     963             : 
     964           0 :     mFrontSurface = surface;
     965           0 :     RecvNPN_InvalidateRect(updatedRect);
     966             : 
     967           0 :     PLUGIN_LOG_DEBUG(("   (RecvShow invalidated for surface %p)",
     968             :                       mFrontSurface.get()));
     969             : 
     970           0 :     RecordDrawingModel();
     971           0 :     return IPC_OK();
     972             : }
     973             : 
     974             : nsresult
     975           0 : PluginInstanceParent::AsyncSetWindow(NPWindow* aWindow)
     976             : {
     977           0 :     NPRemoteWindow window;
     978           0 :     mWindowType = aWindow->type;
     979           0 :     window.window = reinterpret_cast<uint64_t>(aWindow->window);
     980           0 :     window.x = aWindow->x;
     981           0 :     window.y = aWindow->y;
     982           0 :     window.width = aWindow->width;
     983           0 :     window.height = aWindow->height;
     984           0 :     window.clipRect = aWindow->clipRect;
     985           0 :     window.type = aWindow->type;
     986             : #if defined(XP_MACOSX) || defined(XP_WIN)
     987             :     double scaleFactor = 1.0;
     988             :     mNPNIface->getvalue(mNPP, NPNVcontentsScaleFactor, &scaleFactor);
     989             :     window.contentsScaleFactor = scaleFactor;
     990             : #endif
     991             : 
     992             : #if defined(OS_WIN)
     993             :     MaybeCreateChildPopupSurrogate();
     994             : #endif
     995             : 
     996           0 :     if (!SendAsyncSetWindow(gfxPlatform::GetPlatform()->ScreenReferenceSurface()->GetType(),
     997             :                             window))
     998           0 :         return NS_ERROR_FAILURE;
     999             : 
    1000           0 :     return NS_OK;
    1001             : }
    1002             : 
    1003             : nsresult
    1004           0 : PluginInstanceParent::GetImageContainer(ImageContainer** aContainer)
    1005             : {
    1006           0 :     if (IsUsingDirectDrawing()) {
    1007             :         // Use the image container created by the most recent direct surface
    1008             :         // call, if any. We don't create one if no surfaces were presented
    1009             :         // yet.
    1010           0 :         ImageContainer *container = mImageContainer;
    1011           0 :         NS_IF_ADDREF(container);
    1012           0 :         *aContainer = container;
    1013           0 :         return NS_OK;
    1014             :     }
    1015             : 
    1016             : #ifdef XP_MACOSX
    1017             :     MacIOSurface* ioSurface = nullptr;
    1018             : 
    1019             :     if (mFrontIOSurface) {
    1020             :       ioSurface = mFrontIOSurface;
    1021             :     } else if (mIOSurface) {
    1022             :       ioSurface = mIOSurface;
    1023             :     }
    1024             : 
    1025             :     if (!mFrontSurface && !ioSurface)
    1026             : #else
    1027           0 :     if (!mFrontSurface)
    1028             : #endif
    1029           0 :         return NS_ERROR_NOT_AVAILABLE;
    1030             : 
    1031           0 :     ImageContainer *container = GetImageContainer();
    1032             : 
    1033           0 :     if (!container) {
    1034           0 :         return NS_ERROR_FAILURE;
    1035             :     }
    1036             : 
    1037             : #ifdef XP_MACOSX
    1038             :     if (ioSurface) {
    1039             :         RefPtr<Image> image = new MacIOSurfaceImage(ioSurface);
    1040             :         container->SetCurrentImageInTransaction(image);
    1041             : 
    1042             :         NS_IF_ADDREF(container);
    1043             :         *aContainer = container;
    1044             :         return NS_OK;
    1045             :     }
    1046             : #endif
    1047             : 
    1048           0 :     NS_IF_ADDREF(container);
    1049           0 :     *aContainer = container;
    1050           0 :     return NS_OK;
    1051             : }
    1052             : 
    1053             : nsresult
    1054           0 : PluginInstanceParent::GetImageSize(nsIntSize* aSize)
    1055             : {
    1056           0 :     if (IsUsingDirectDrawing()) {
    1057           0 :         if (!mImageContainer) {
    1058           0 :             return NS_ERROR_NOT_AVAILABLE;
    1059             :         }
    1060           0 :         *aSize = mImageContainer->GetCurrentSize();
    1061           0 :         return NS_OK;
    1062             :     }
    1063             : 
    1064           0 :     if (mFrontSurface) {
    1065           0 :         mozilla::gfx::IntSize size = mFrontSurface->GetSize();
    1066           0 :         *aSize = nsIntSize(size.width, size.height);
    1067           0 :         return NS_OK;
    1068             :     }
    1069             : 
    1070             : #ifdef XP_MACOSX
    1071             :     if (mFrontIOSurface) {
    1072             :         *aSize = nsIntSize(mFrontIOSurface->GetWidth(), mFrontIOSurface->GetHeight());
    1073             :         return NS_OK;
    1074             :     } else if (mIOSurface) {
    1075             :         *aSize = nsIntSize(mIOSurface->GetWidth(), mIOSurface->GetHeight());
    1076             :         return NS_OK;
    1077             :     }
    1078             : #endif
    1079             : 
    1080           0 :     return NS_ERROR_NOT_AVAILABLE;
    1081             : }
    1082             : 
    1083             : void
    1084           0 : PluginInstanceParent::DidComposite()
    1085             : {
    1086           0 :     if (!IsUsingDirectDrawing()) {
    1087           0 :         return;
    1088             :     }
    1089           0 :     Unused << SendNPP_DidComposite();
    1090             : }
    1091             : 
    1092             : #ifdef XP_MACOSX
    1093             : nsresult
    1094             : PluginInstanceParent::IsRemoteDrawingCoreAnimation(bool *aDrawing)
    1095             : {
    1096             :     *aDrawing = (NPDrawingModelCoreAnimation == (NPDrawingModel)mDrawingModel ||
    1097             :                  NPDrawingModelInvalidatingCoreAnimation == (NPDrawingModel)mDrawingModel);
    1098             :     return NS_OK;
    1099             : }
    1100             : #endif
    1101             : #if defined(XP_MACOSX) || defined(XP_WIN)
    1102             : nsresult
    1103             : PluginInstanceParent::ContentsScaleFactorChanged(double aContentsScaleFactor)
    1104             : {
    1105             :     bool rv = SendContentsScaleFactorChanged(aContentsScaleFactor);
    1106             :     return rv ? NS_OK : NS_ERROR_FAILURE;
    1107             : }
    1108             : #endif // #ifdef XP_MACOSX
    1109             : 
    1110             : nsresult
    1111           0 : PluginInstanceParent::SetBackgroundUnknown()
    1112             : {
    1113           0 :     PLUGIN_LOG_DEBUG(("[InstanceParent][%p] SetBackgroundUnknown", this));
    1114             : 
    1115           0 :     if (mBackground) {
    1116           0 :         DestroyBackground();
    1117           0 :         MOZ_ASSERT(!mBackground, "Background not destroyed");
    1118             :     }
    1119             : 
    1120           0 :     return NS_OK;
    1121             : }
    1122             : 
    1123             : nsresult
    1124           0 : PluginInstanceParent::BeginUpdateBackground(const nsIntRect& aRect,
    1125             :                                             DrawTarget** aDrawTarget)
    1126             : {
    1127           0 :     PLUGIN_LOG_DEBUG(
    1128             :         ("[InstanceParent][%p] BeginUpdateBackground for <x=%d,y=%d, w=%d,h=%d>",
    1129             :          this, aRect.x, aRect.y, aRect.width, aRect.height));
    1130             : 
    1131           0 :     if (!mBackground) {
    1132             :         // XXX if we failed to create a background surface on one
    1133             :         // update, there's no guarantee that later updates will be for
    1134             :         // the entire background area until successful.  We might want
    1135             :         // to fix that eventually.
    1136           0 :         MOZ_ASSERT(aRect.TopLeft() == nsIntPoint(0, 0),
    1137             :                    "Expecting rect for whole frame");
    1138           0 :         if (!CreateBackground(aRect.Size())) {
    1139           0 :             *aDrawTarget = nullptr;
    1140           0 :             return NS_OK;
    1141             :         }
    1142             :     }
    1143             : 
    1144           0 :     mozilla::gfx::IntSize sz = mBackground->GetSize();
    1145             : #ifdef DEBUG
    1146           0 :     MOZ_ASSERT(nsIntRect(0, 0, sz.width, sz.height).Contains(aRect),
    1147             :                "Update outside of background area");
    1148             : #endif
    1149             : 
    1150           0 :     RefPtr<gfx::DrawTarget> dt = gfxPlatform::GetPlatform()->
    1151           0 :       CreateDrawTargetForSurface(mBackground, gfx::IntSize(sz.width, sz.height));
    1152           0 :     dt.forget(aDrawTarget);
    1153             : 
    1154           0 :     return NS_OK;
    1155             : }
    1156             : 
    1157             : nsresult
    1158           0 : PluginInstanceParent::EndUpdateBackground(const nsIntRect& aRect)
    1159             : {
    1160           0 :     PLUGIN_LOG_DEBUG(
    1161             :         ("[InstanceParent][%p] EndUpdateBackground for <x=%d,y=%d, w=%d,h=%d>",
    1162             :          this, aRect.x, aRect.y, aRect.width, aRect.height));
    1163             : 
    1164             : #ifdef MOZ_X11
    1165             :     // Have to XSync here to avoid the plugin trying to draw with this
    1166             :     // surface racing with its creation in the X server.  We also want
    1167             :     // to avoid the plugin drawing onto stale pixels, then handing us
    1168             :     // back a front surface from those pixels that we might
    1169             :     // recomposite for "a while" until the next update.  This XSync
    1170             :     // still doesn't guarantee that the plugin draws onto a consistent
    1171             :     // view of its background, but it does mean that the plugin is
    1172             :     // drawing onto pixels no older than those in the latest
    1173             :     // EndUpdateBackground().
    1174           0 :     XSync(DefaultXDisplay(), False);
    1175             : #endif
    1176             : 
    1177           0 :     Unused << SendUpdateBackground(BackgroundDescriptor(), aRect);
    1178             : 
    1179           0 :     return NS_OK;
    1180             : }
    1181             : 
    1182             : #if defined(XP_WIN)
    1183             : nsresult
    1184             : PluginInstanceParent::SetScrollCaptureId(uint64_t aScrollCaptureId)
    1185             : {
    1186             :   if (aScrollCaptureId == ImageContainer::sInvalidAsyncContainerId) {
    1187             :     return NS_ERROR_FAILURE;
    1188             :   }
    1189             : 
    1190             :   mImageContainer = new ImageContainer(CompositableHandle(aScrollCaptureId));
    1191             :   return NS_OK;
    1192             : }
    1193             : 
    1194             : nsresult
    1195             : PluginInstanceParent::GetScrollCaptureContainer(ImageContainer** aContainer)
    1196             : {
    1197             :   if (!aContainer || !mImageContainer) {
    1198             :     return NS_ERROR_FAILURE;
    1199             :   }
    1200             : 
    1201             :   RefPtr<ImageContainer> container = GetImageContainer();
    1202             :   container.forget(aContainer);
    1203             : 
    1204             :   return NS_OK;
    1205             : }
    1206             : #endif // XP_WIN
    1207             : 
    1208             : bool
    1209           0 : PluginInstanceParent::CreateBackground(const nsIntSize& aSize)
    1210             : {
    1211           0 :     MOZ_ASSERT(!mBackground, "Already have a background");
    1212             : 
    1213             :     // XXX refactor me
    1214             : 
    1215             : #if defined(MOZ_X11)
    1216           0 :     Screen* screen = DefaultScreenOfDisplay(DefaultXDisplay());
    1217           0 :     Visual* visual = DefaultVisualOfScreen(screen);
    1218           0 :     mBackground = gfxXlibSurface::Create(screen, visual,
    1219           0 :                                          mozilla::gfx::IntSize(aSize.width, aSize.height));
    1220           0 :     return !!mBackground;
    1221             : 
    1222             : #elif defined(XP_WIN)
    1223             :     // We have chosen to create an unsafe surface in which the plugin
    1224             :     // can read from the region while we're writing to it.
    1225             :     mBackground =
    1226             :         gfxSharedImageSurface::CreateUnsafe(
    1227             :             this,
    1228             :             mozilla::gfx::IntSize(aSize.width, aSize.height),
    1229             :             mozilla::gfx::SurfaceFormat::X8R8G8B8_UINT32);
    1230             :     return !!mBackground;
    1231             : #else
    1232             :     return false;
    1233             : #endif
    1234             : }
    1235             : 
    1236             : void
    1237           0 : PluginInstanceParent::DestroyBackground()
    1238             : {
    1239           0 :     if (!mBackground) {
    1240           0 :         return;
    1241             :     }
    1242             : 
    1243             :     // Relinquish ownership of |mBackground| to its destroyer
    1244             :     PPluginBackgroundDestroyerParent* pbd =
    1245           0 :         new PluginBackgroundDestroyerParent(mBackground);
    1246           0 :     mBackground = nullptr;
    1247             : 
    1248             :     // If this fails, there's no problem: |bd| will be destroyed along
    1249             :     // with the old background surface.
    1250           0 :     Unused << SendPPluginBackgroundDestroyerConstructor(pbd);
    1251             : }
    1252             : 
    1253             : mozilla::plugins::SurfaceDescriptor
    1254           0 : PluginInstanceParent::BackgroundDescriptor()
    1255             : {
    1256           0 :     MOZ_ASSERT(mBackground, "Need a background here");
    1257             : 
    1258             :     // XXX refactor me
    1259             : 
    1260             : #ifdef MOZ_X11
    1261           0 :     gfxXlibSurface* xsurf = static_cast<gfxXlibSurface*>(mBackground.get());
    1262           0 :     return SurfaceDescriptorX11(xsurf);
    1263             : #endif
    1264             : 
    1265             : #ifdef XP_WIN
    1266             :     MOZ_ASSERT(gfxSharedImageSurface::IsSharedImage(mBackground),
    1267             :                "Expected shared image surface");
    1268             :     gfxSharedImageSurface* shmem =
    1269             :         static_cast<gfxSharedImageSurface*>(mBackground.get());
    1270             :     return shmem->GetShmem();
    1271             : #endif
    1272             : 
    1273             :     // If this is ever used, which it shouldn't be, it will trigger a
    1274             :     // hard assertion in IPDL-generated code.
    1275             :     return mozilla::plugins::SurfaceDescriptor();
    1276             : }
    1277             : 
    1278             : ImageContainer*
    1279           0 : PluginInstanceParent::GetImageContainer()
    1280             : {
    1281           0 :   if (mImageContainer) {
    1282           0 :     return mImageContainer;
    1283             :   }
    1284             : 
    1285           0 :   if (IsUsingDirectDrawing()) {
    1286           0 :       mImageContainer = LayerManager::CreateImageContainer(ImageContainer::ASYNCHRONOUS);
    1287             :   } else {
    1288           0 :       mImageContainer = LayerManager::CreateImageContainer();
    1289             :   }
    1290           0 :   return mImageContainer;
    1291             : }
    1292             : 
    1293             : PPluginBackgroundDestroyerParent*
    1294           0 : PluginInstanceParent::AllocPPluginBackgroundDestroyerParent()
    1295             : {
    1296           0 :     MOZ_CRASH("'Power-user' ctor is used exclusively");
    1297             :     return nullptr;
    1298             : }
    1299             : 
    1300             : bool
    1301           0 : PluginInstanceParent::DeallocPPluginBackgroundDestroyerParent(
    1302             :     PPluginBackgroundDestroyerParent* aActor)
    1303             : {
    1304           0 :     delete aActor;
    1305           0 :     return true;
    1306             : }
    1307             : 
    1308             : NPError
    1309           0 : PluginInstanceParent::NPP_SetWindow(const NPWindow* aWindow)
    1310             : {
    1311           0 :     PLUGIN_LOG_DEBUG(("%s (aWindow=%p)", FULLFUNCTION, (void*) aWindow));
    1312             : 
    1313           0 :     NS_ENSURE_TRUE(aWindow, NPERR_GENERIC_ERROR);
    1314             : 
    1315           0 :     NPRemoteWindow window;
    1316           0 :     mWindowType = aWindow->type;
    1317             : 
    1318             : #if defined(OS_WIN)
    1319             :     // On windowless controls, reset the shared memory surface as needed.
    1320             :     if (mWindowType == NPWindowTypeDrawable) {
    1321             :         MaybeCreateChildPopupSurrogate();
    1322             :     } else {
    1323             :         SubclassPluginWindow(reinterpret_cast<HWND>(aWindow->window));
    1324             : 
    1325             :         window.window = reinterpret_cast<uint64_t>(aWindow->window);
    1326             :         window.x = aWindow->x;
    1327             :         window.y = aWindow->y;
    1328             :         window.width = aWindow->width;
    1329             :         window.height = aWindow->height;
    1330             :         window.type = aWindow->type;
    1331             : 
    1332             :         // On Windows we need to create and set the parent before we set the
    1333             :         // window on the plugin, or keyboard interaction will not work.
    1334             :         if (!MaybeCreateAndParentChildPluginWindow()) {
    1335             :             return NPERR_GENERIC_ERROR;
    1336             :         }
    1337             :     }
    1338             : #else
    1339           0 :     window.window = reinterpret_cast<uint64_t>(aWindow->window);
    1340           0 :     window.x = aWindow->x;
    1341           0 :     window.y = aWindow->y;
    1342           0 :     window.width = aWindow->width;
    1343           0 :     window.height = aWindow->height;
    1344           0 :     window.clipRect = aWindow->clipRect; // MacOS specific
    1345           0 :     window.type = aWindow->type;
    1346             : #endif
    1347             : 
    1348             : #if defined(XP_MACOSX) || defined(XP_WIN)
    1349             :     double floatScaleFactor = 1.0;
    1350             :     mNPNIface->getvalue(mNPP, NPNVcontentsScaleFactor, &floatScaleFactor);
    1351             :     int scaleFactor = ceil(floatScaleFactor);
    1352             :     window.contentsScaleFactor = floatScaleFactor;
    1353             : #endif
    1354             : #if defined(XP_MACOSX)
    1355             :     if (mShWidth != window.width * scaleFactor || mShHeight != window.height * scaleFactor) {
    1356             :         if (mDrawingModel == NPDrawingModelCoreAnimation ||
    1357             :             mDrawingModel == NPDrawingModelInvalidatingCoreAnimation) {
    1358             :             mIOSurface = MacIOSurface::CreateIOSurface(window.width, window.height,
    1359             :                                                        floatScaleFactor);
    1360             :         } else if (uint32_t(mShWidth * mShHeight) !=
    1361             :                    window.width * scaleFactor * window.height * scaleFactor) {
    1362             :             if (mShWidth != 0 && mShHeight != 0) {
    1363             :                 DeallocShmem(mShSurface);
    1364             :                 mShWidth = 0;
    1365             :                 mShHeight = 0;
    1366             :             }
    1367             : 
    1368             :             if (window.width != 0 && window.height != 0) {
    1369             :                 if (!AllocShmem(window.width * scaleFactor * window.height*4 * scaleFactor,
    1370             :                                 SharedMemory::TYPE_BASIC, &mShSurface)) {
    1371             :                     PLUGIN_LOG_DEBUG(("Shared memory could not be allocated."));
    1372             :                     return NPERR_GENERIC_ERROR;
    1373             :                 }
    1374             :             }
    1375             :         }
    1376             :         mShWidth = window.width * scaleFactor;
    1377             :         mShHeight = window.height * scaleFactor;
    1378             :     }
    1379             : #endif
    1380             : 
    1381             : #if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
    1382             :     const NPSetWindowCallbackStruct* ws_info =
    1383           0 :       static_cast<NPSetWindowCallbackStruct*>(aWindow->ws_info);
    1384           0 :     window.visualID = ws_info->visual ? ws_info->visual->visualid : 0;
    1385           0 :     window.colormap = ws_info->colormap;
    1386             : #endif
    1387             : 
    1388           0 :     if (!CallNPP_SetWindow(window)) {
    1389           0 :         return NPERR_GENERIC_ERROR;
    1390             :     }
    1391             : 
    1392           0 :     RecordDrawingModel();
    1393           0 :     return NPERR_NO_ERROR;
    1394             : }
    1395             : 
    1396             : NPError
    1397           0 : PluginInstanceParent::NPP_GetValue(NPPVariable aVariable,
    1398             :                                    void* _retval)
    1399             : {
    1400           0 :     switch (aVariable) {
    1401             : 
    1402             :     case NPPVpluginWantsAllNetworkStreams: {
    1403             :         bool wantsAllStreams;
    1404             :         NPError rv;
    1405             : 
    1406           0 :         if (!CallNPP_GetValue_NPPVpluginWantsAllNetworkStreams(&wantsAllStreams, &rv)) {
    1407           0 :             return NPERR_GENERIC_ERROR;
    1408             :         }
    1409             : 
    1410           0 :         if (NPERR_NO_ERROR != rv) {
    1411           0 :             return rv;
    1412             :         }
    1413             : 
    1414           0 :         (*(NPBool*)_retval) = wantsAllStreams;
    1415           0 :         return NPERR_NO_ERROR;
    1416             :     }
    1417             : 
    1418             :     case NPPVpluginScriptableNPObject: {
    1419             :         PPluginScriptableObjectParent* actor;
    1420             :         NPError rv;
    1421           0 :         if (!CallNPP_GetValue_NPPVpluginScriptableNPObject(&actor, &rv)) {
    1422           0 :             return NPERR_GENERIC_ERROR;
    1423             :         }
    1424             : 
    1425           0 :         if (NPERR_NO_ERROR != rv) {
    1426           0 :             return rv;
    1427             :         }
    1428             : 
    1429           0 :         if (!actor) {
    1430           0 :             NS_ERROR("NPPVpluginScriptableNPObject succeeded but null.");
    1431           0 :             return NPERR_GENERIC_ERROR;
    1432             :         }
    1433             : 
    1434           0 :         const NPNetscapeFuncs* npn = mParent->GetNetscapeFuncs();
    1435           0 :         if (!npn) {
    1436           0 :             NS_WARNING("No netscape functions?!");
    1437           0 :             return NPERR_GENERIC_ERROR;
    1438             :         }
    1439             : 
    1440             :         NPObject* object =
    1441           0 :             static_cast<PluginScriptableObjectParent*>(actor)->GetObject(true);
    1442           0 :         NS_ASSERTION(object, "This shouldn't ever be null!");
    1443             : 
    1444           0 :         (*(NPObject**)_retval) = npn->retainobject(object);
    1445           0 :         return NPERR_NO_ERROR;
    1446             :     }
    1447             : 
    1448             : #ifdef MOZ_ACCESSIBILITY_ATK
    1449             :     case NPPVpluginNativeAccessibleAtkPlugId: {
    1450           0 :         nsCString plugId;
    1451             :         NPError rv;
    1452           0 :         if (!CallNPP_GetValue_NPPVpluginNativeAccessibleAtkPlugId(&plugId, &rv)) {
    1453           0 :             return NPERR_GENERIC_ERROR;
    1454             :         }
    1455             : 
    1456           0 :         if (NPERR_NO_ERROR != rv) {
    1457           0 :             return rv;
    1458             :         }
    1459             : 
    1460           0 :         (*(nsCString*)_retval) = plugId;
    1461           0 :         return NPERR_NO_ERROR;
    1462             :     }
    1463             : #endif
    1464             : 
    1465             :     default:
    1466           0 :         MOZ_LOG(GetPluginLog(), LogLevel::Warning,
    1467             :                ("In PluginInstanceParent::NPP_GetValue: Unhandled NPPVariable %i (%s)",
    1468             :                 (int) aVariable, NPPVariableToString(aVariable)));
    1469           0 :         return NPERR_GENERIC_ERROR;
    1470             :     }
    1471             : }
    1472             : 
    1473             : NPError
    1474           0 : PluginInstanceParent::NPP_SetValue(NPNVariable variable, void* value)
    1475             : {
    1476             :     NPError result;
    1477           0 :     switch (variable) {
    1478             :     case NPNVprivateModeBool:
    1479           0 :         if (!CallNPP_SetValue_NPNVprivateModeBool(*static_cast<NPBool*>(value),
    1480           0 :                                                   &result))
    1481           0 :             return NPERR_GENERIC_ERROR;
    1482             : 
    1483           0 :         return result;
    1484             : 
    1485             :     case NPNVmuteAudioBool:
    1486           0 :         if (!CallNPP_SetValue_NPNVmuteAudioBool(*static_cast<NPBool*>(value),
    1487           0 :                                                 &result))
    1488           0 :             return NPERR_GENERIC_ERROR;
    1489             : 
    1490           0 :         return result;
    1491             : 
    1492             :     case NPNVCSSZoomFactor:
    1493           0 :         if (!CallNPP_SetValue_NPNVCSSZoomFactor(*static_cast<double*>(value),
    1494             :                                                 &result))
    1495           0 :             return NPERR_GENERIC_ERROR;
    1496             : 
    1497           0 :         return result;
    1498             : 
    1499             :     default:
    1500           0 :         NS_ERROR("Unhandled NPNVariable in NPP_SetValue");
    1501           0 :         MOZ_LOG(GetPluginLog(), LogLevel::Warning,
    1502             :                ("In PluginInstanceParent::NPP_SetValue: Unhandled NPNVariable %i (%s)",
    1503             :                 (int) variable, NPNVariableToString(variable)));
    1504           0 :         return NPERR_GENERIC_ERROR;
    1505             :     }
    1506             : }
    1507             : 
    1508             : void
    1509           0 : PluginInstanceParent::NPP_URLRedirectNotify(const char* url, int32_t status,
    1510             :                                             void* notifyData)
    1511             : {
    1512           0 :   if (!notifyData)
    1513           0 :     return;
    1514             : 
    1515           0 :   PStreamNotifyParent* streamNotify = static_cast<PStreamNotifyParent*>(notifyData);
    1516           0 :   Unused << streamNotify->SendRedirectNotify(NullableString(url), status);
    1517             : }
    1518             : 
    1519             : int16_t
    1520           0 : PluginInstanceParent::NPP_HandleEvent(void* event)
    1521             : {
    1522           0 :     PLUGIN_LOG_DEBUG_FUNCTION;
    1523             : 
    1524             : #if defined(XP_MACOSX)
    1525             :     NPCocoaEvent* npevent = reinterpret_cast<NPCocoaEvent*>(event);
    1526             : #else
    1527           0 :     NPEvent* npevent = reinterpret_cast<NPEvent*>(event);
    1528             : #endif
    1529             :     NPRemoteEvent npremoteevent;
    1530           0 :     npremoteevent.event = *npevent;
    1531             : #if defined(XP_MACOSX) || defined(XP_WIN)
    1532             :     double scaleFactor = 1.0;
    1533             :     mNPNIface->getvalue(mNPP, NPNVcontentsScaleFactor, &scaleFactor);
    1534             :     npremoteevent.contentsScaleFactor = scaleFactor;
    1535             : #endif
    1536           0 :     int16_t handled = 0;
    1537             : 
    1538             : #if defined(OS_WIN)
    1539             :     if (mWindowType == NPWindowTypeDrawable) {
    1540             :         switch (npevent->event) {
    1541             :             case WM_KILLFOCUS:
    1542             :             {
    1543             :               // When the user selects fullscreen mode in Flash video players,
    1544             :               // WM_KILLFOCUS will be delayed by deferred event processing:
    1545             :               // WM_LBUTTONUP results in a call to CreateWindow within Flash,
    1546             :               // which fires WM_KILLFOCUS. Delayed delivery causes Flash to
    1547             :               // misinterpret the event, dropping back out of fullscreen. Trap
    1548             :               // this event and drop it.
    1549             :               wchar_t szClass[26];
    1550             :               HWND hwnd = GetForegroundWindow();
    1551             :               if (hwnd && hwnd != mPluginHWND &&
    1552             :                   GetClassNameW(hwnd, szClass,
    1553             :                                 sizeof(szClass)/sizeof(char16_t)) &&
    1554             :                   !wcscmp(szClass, kFlashFullscreenClass)) {
    1555             :                   return 0;
    1556             :               }
    1557             :             }
    1558             :             break;
    1559             : 
    1560             :             case WM_WINDOWPOSCHANGED:
    1561             :             {
    1562             :                 // We send this in nsPluginFrame just before painting
    1563             :                 return SendWindowPosChanged(npremoteevent);
    1564             :             }
    1565             : 
    1566             :             case WM_IME_STARTCOMPOSITION:
    1567             :             case WM_IME_COMPOSITION:
    1568             :             case WM_IME_ENDCOMPOSITION:
    1569             :                 if (!(mParent->GetQuirks() & QUIRK_WINLESS_HOOK_IME)) {
    1570             :                   // IME message will be posted on allowed plugins only such as
    1571             :                   // Flash.  Because if we cannot know that plugin can handle
    1572             :                   // IME correctly.
    1573             :                   return 0;
    1574             :                 }
    1575             :             break;
    1576             :         }
    1577             :     }
    1578             : #endif
    1579             : 
    1580             : #if defined(MOZ_X11)
    1581           0 :     switch (npevent->type) {
    1582             :     case GraphicsExpose:
    1583           0 :         PLUGIN_LOG_DEBUG(("  schlepping drawable 0x%lx across the pipe\n",
    1584             :                           npevent->xgraphicsexpose.drawable));
    1585             :         // Make sure the X server has created the Drawable and completes any
    1586             :         // drawing before the plugin draws on top.
    1587             :         //
    1588             :         // XSync() waits for the X server to complete.  Really this parent
    1589             :         // process does not need to wait; the child is the process that needs
    1590             :         // to wait.  A possibly-slightly-better alternative would be to send
    1591             :         // an X event to the child that the child would wait for.
    1592           0 :         FinishX(DefaultXDisplay());
    1593             : 
    1594           0 :         return CallPaint(npremoteevent, &handled) ? handled : 0;
    1595             : 
    1596             :     case ButtonPress:
    1597             :         // Release any active pointer grab so that the plugin X client can
    1598             :         // grab the pointer if it wishes.
    1599           0 :         Display *dpy = DefaultXDisplay();
    1600             : #  ifdef MOZ_WIDGET_GTK
    1601             :         // GDK attempts to (asynchronously) track whether there is an active
    1602             :         // grab so ungrab through GDK.
    1603             :         //
    1604             :         // This call needs to occur in the same process that receives the event in
    1605             :         // the first place (chrome process)
    1606           0 :         if (XRE_IsContentProcess()) {
    1607           0 :           dom::ContentChild* cp = dom::ContentChild::GetSingleton();
    1608           0 :           cp->SendUngrabPointer(npevent->xbutton.time);
    1609             :         } else {
    1610           0 :           gdk_pointer_ungrab(npevent->xbutton.time);
    1611             :         }
    1612             : #  else
    1613             :         XUngrabPointer(dpy, npevent->xbutton.time);
    1614             : #  endif
    1615             :         // Wait for the ungrab to complete.
    1616           0 :         XSync(dpy, False);
    1617           0 :         break;
    1618             :     }
    1619             : #endif
    1620             : 
    1621             : #ifdef XP_MACOSX
    1622             :     if (npevent->type == NPCocoaEventDrawRect) {
    1623             :         if (mDrawingModel == NPDrawingModelCoreAnimation ||
    1624             :             mDrawingModel == NPDrawingModelInvalidatingCoreAnimation) {
    1625             :             if (!mIOSurface) {
    1626             :                 NS_ERROR("No IOSurface allocated.");
    1627             :                 return false;
    1628             :             }
    1629             :             if (!CallNPP_HandleEvent_IOSurface(npremoteevent,
    1630             :                                                mIOSurface->GetIOSurfaceID(),
    1631             :                                                &handled))
    1632             :                 return false; // no good way to handle errors here...
    1633             : 
    1634             :             CGContextRef cgContext = npevent->data.draw.context;
    1635             :             if (!mShColorSpace) {
    1636             :                 mShColorSpace = CreateSystemColorSpace();
    1637             :             }
    1638             :             if (!mShColorSpace) {
    1639             :                 PLUGIN_LOG_DEBUG(("Could not allocate ColorSpace."));
    1640             :                 return false;
    1641             :             }
    1642             :             if (cgContext) {
    1643             :                 nsCARenderer::DrawSurfaceToCGContext(cgContext, mIOSurface,
    1644             :                                                      mShColorSpace,
    1645             :                                                      npevent->data.draw.x,
    1646             :                                                      npevent->data.draw.y,
    1647             :                                                      npevent->data.draw.width,
    1648             :                                                      npevent->data.draw.height);
    1649             :             }
    1650             :             return true;
    1651             :         } else if (mFrontIOSurface) {
    1652             :             CGContextRef cgContext = npevent->data.draw.context;
    1653             :             if (!mShColorSpace) {
    1654             :                 mShColorSpace = CreateSystemColorSpace();
    1655             :             }
    1656             :             if (!mShColorSpace) {
    1657             :                 PLUGIN_LOG_DEBUG(("Could not allocate ColorSpace."));
    1658             :                 return false;
    1659             :             }
    1660             :             if (cgContext) {
    1661             :                 nsCARenderer::DrawSurfaceToCGContext(cgContext, mFrontIOSurface,
    1662             :                                                      mShColorSpace,
    1663             :                                                      npevent->data.draw.x,
    1664             :                                                      npevent->data.draw.y,
    1665             :                                                      npevent->data.draw.width,
    1666             :                                                      npevent->data.draw.height);
    1667             :             }
    1668             :             return true;
    1669             :         } else {
    1670             :             if (mShWidth == 0 && mShHeight == 0) {
    1671             :                 PLUGIN_LOG_DEBUG(("NPCocoaEventDrawRect on window of size 0."));
    1672             :                 return false;
    1673             :             }
    1674             :             if (!mShSurface.IsReadable()) {
    1675             :                 PLUGIN_LOG_DEBUG(("Shmem is not readable."));
    1676             :                 return false;
    1677             :             }
    1678             : 
    1679             :             if (!CallNPP_HandleEvent_Shmem(npremoteevent, mShSurface,
    1680             :                                            &handled, &mShSurface))
    1681             :                 return false; // no good way to handle errors here...
    1682             : 
    1683             :             if (!mShSurface.IsReadable()) {
    1684             :                 PLUGIN_LOG_DEBUG(("Shmem not returned. Either the plugin crashed "
    1685             :                                   "or we have a bug."));
    1686             :                 return false;
    1687             :             }
    1688             : 
    1689             :             char* shContextByte = mShSurface.get<char>();
    1690             : 
    1691             :             if (!mShColorSpace) {
    1692             :                 mShColorSpace = CreateSystemColorSpace();
    1693             :             }
    1694             :             if (!mShColorSpace) {
    1695             :                 PLUGIN_LOG_DEBUG(("Could not allocate ColorSpace."));
    1696             :                 return false;
    1697             :             }
    1698             :             CGContextRef shContext = ::CGBitmapContextCreate(shContextByte,
    1699             :                                     mShWidth, mShHeight, 8,
    1700             :                                     mShWidth*4, mShColorSpace,
    1701             :                                     kCGImageAlphaPremultipliedFirst |
    1702             :                                     kCGBitmapByteOrder32Host);
    1703             :             if (!shContext) {
    1704             :                 PLUGIN_LOG_DEBUG(("Could not allocate CGBitmapContext."));
    1705             :                 return false;
    1706             :             }
    1707             : 
    1708             :             CGImageRef shImage = ::CGBitmapContextCreateImage(shContext);
    1709             :             if (shImage) {
    1710             :                 CGContextRef cgContext = npevent->data.draw.context;
    1711             : 
    1712             :                 ::CGContextDrawImage(cgContext,
    1713             :                                      CGRectMake(0,0,mShWidth,mShHeight),
    1714             :                                      shImage);
    1715             :                 ::CGImageRelease(shImage);
    1716             :             } else {
    1717             :                 ::CGContextRelease(shContext);
    1718             :                 return false;
    1719             :             }
    1720             :             ::CGContextRelease(shContext);
    1721             :             return true;
    1722             :         }
    1723             :     }
    1724             : #endif
    1725             : 
    1726           0 :     if (!CallNPP_HandleEvent(npremoteevent, &handled))
    1727           0 :         return 0; // no good way to handle errors here...
    1728             : 
    1729           0 :     return handled;
    1730             : }
    1731             : 
    1732             : NPError
    1733           0 : PluginInstanceParent::NPP_NewStream(NPMIMEType type, NPStream* stream,
    1734             :                                     NPBool seekable, uint16_t* stype)
    1735             : {
    1736           0 :     PLUGIN_LOG_DEBUG(("%s (type=%s, stream=%p, seekable=%i)",
    1737             :                       FULLFUNCTION, (char*) type, (void*) stream, (int) seekable));
    1738             : 
    1739           0 :     BrowserStreamParent* bs = new BrowserStreamParent(this, stream);
    1740             : 
    1741           0 :     if (!SendPBrowserStreamConstructor(bs,
    1742           0 :                                        NullableString(stream->url),
    1743             :                                        stream->end,
    1744             :                                        stream->lastmodified,
    1745           0 :                                        static_cast<PStreamNotifyParent*>(stream->notifyData),
    1746           0 :                                        NullableString(stream->headers))) {
    1747           0 :         return NPERR_GENERIC_ERROR;
    1748             :     }
    1749             : 
    1750             :     Telemetry::AutoTimer<Telemetry::BLOCKED_ON_PLUGIN_STREAM_INIT_MS>
    1751           0 :         timer(Module()->GetHistogramKey());
    1752             : 
    1753           0 :     NPError err = NPERR_NO_ERROR;
    1754           0 :     bs->SetAlive();
    1755           0 :     if (!CallNPP_NewStream(bs, NullableString(type), seekable, &err, stype)) {
    1756           0 :         err = NPERR_GENERIC_ERROR;
    1757             :     }
    1758           0 :     if (NPERR_NO_ERROR != err) {
    1759           0 :         Unused << PBrowserStreamParent::Send__delete__(bs);
    1760             :     }
    1761             : 
    1762           0 :     return err;
    1763             : }
    1764             : 
    1765             : NPError
    1766           0 : PluginInstanceParent::NPP_DestroyStream(NPStream* stream, NPReason reason)
    1767             : {
    1768           0 :     PLUGIN_LOG_DEBUG(("%s (stream=%p, reason=%i)",
    1769             :                       FULLFUNCTION, (void*) stream, (int) reason));
    1770             : 
    1771           0 :     AStream* s = static_cast<AStream*>(stream->pdata);
    1772           0 :     if (!s) {
    1773             :         // The stream has already been deleted by other means.
    1774             :         // With async plugin init this could happen if async NPP_NewStream
    1775             :         // returns an error code.
    1776           0 :         return NPERR_NO_ERROR;
    1777             :     }
    1778           0 :     MOZ_ASSERT(s->IsBrowserStream());
    1779             :     BrowserStreamParent* sp =
    1780           0 :         static_cast<BrowserStreamParent*>(s);
    1781           0 :     if (sp->mNPP != this)
    1782           0 :         MOZ_CRASH("Mismatched plugin data");
    1783           0 :     sp->NPP_DestroyStream(reason);
    1784           0 :     return NPERR_NO_ERROR;
    1785             : }
    1786             : 
    1787             : void
    1788           0 : PluginInstanceParent::NPP_Print(NPPrint* platformPrint)
    1789             : {
    1790             :     // TODO: implement me
    1791           0 :     NS_ERROR("Not implemented");
    1792           0 : }
    1793             : 
    1794             : PPluginScriptableObjectParent*
    1795           0 : PluginInstanceParent::AllocPPluginScriptableObjectParent()
    1796             : {
    1797           0 :     return new PluginScriptableObjectParent(Proxy);
    1798             : }
    1799             : 
    1800             : bool
    1801           0 : PluginInstanceParent::DeallocPPluginScriptableObjectParent(
    1802             :                                          PPluginScriptableObjectParent* aObject)
    1803             : {
    1804             :     PluginScriptableObjectParent* actor =
    1805           0 :         static_cast<PluginScriptableObjectParent*>(aObject);
    1806             : 
    1807           0 :     NPObject* object = actor->GetObject(false);
    1808           0 :     if (object) {
    1809           0 :         NS_ASSERTION(mScriptableObjects.Get(object, nullptr),
    1810             :                      "NPObject not in the hash!");
    1811           0 :         mScriptableObjects.Remove(object);
    1812             :     }
    1813             : #ifdef DEBUG
    1814             :     else {
    1815           0 :         for (auto iter = mScriptableObjects.Iter(); !iter.Done(); iter.Next()) {
    1816           0 :             NS_ASSERTION(actor != iter.UserData(),
    1817             :                          "Actor in the hash with a null NPObject!");
    1818             :         }
    1819             :     }
    1820             : #endif
    1821             : 
    1822           0 :     delete actor;
    1823           0 :     return true;
    1824             : }
    1825             : 
    1826             : mozilla::ipc::IPCResult
    1827           0 : PluginInstanceParent::RecvPPluginScriptableObjectConstructor(
    1828             :                                           PPluginScriptableObjectParent* aActor)
    1829             : {
    1830             :     // This is only called in response to the child process requesting the
    1831             :     // creation of an actor. This actor will represent an NPObject that is
    1832             :     // created by the plugin and returned to the browser.
    1833             :     PluginScriptableObjectParent* actor =
    1834           0 :         static_cast<PluginScriptableObjectParent*>(aActor);
    1835           0 :     NS_ASSERTION(!actor->GetObject(false), "Actor already has an object?!");
    1836             : 
    1837           0 :     actor->InitializeProxy();
    1838           0 :     NS_ASSERTION(actor->GetObject(false), "Actor should have an object!");
    1839             : 
    1840           0 :     return IPC_OK();
    1841             : }
    1842             : 
    1843             : void
    1844           0 : PluginInstanceParent::NPP_URLNotify(const char* url, NPReason reason,
    1845             :                                     void* notifyData)
    1846             : {
    1847           0 :     PLUGIN_LOG_DEBUG(("%s (%s, %i, %p)",
    1848             :                       FULLFUNCTION, url, (int) reason, notifyData));
    1849             : 
    1850             :     PStreamNotifyParent* streamNotify =
    1851           0 :         static_cast<PStreamNotifyParent*>(notifyData);
    1852           0 :     Unused << PStreamNotifyParent::Send__delete__(streamNotify, reason);
    1853           0 : }
    1854             : 
    1855             : bool
    1856           0 : PluginInstanceParent::RegisterNPObjectForActor(
    1857             :                                            NPObject* aObject,
    1858             :                                            PluginScriptableObjectParent* aActor)
    1859             : {
    1860           0 :     NS_ASSERTION(aObject && aActor, "Null pointers!");
    1861           0 :     NS_ASSERTION(!mScriptableObjects.Get(aObject, nullptr), "Duplicate entry!");
    1862           0 :     mScriptableObjects.Put(aObject, aActor);
    1863           0 :     return true;
    1864             : }
    1865             : 
    1866             : void
    1867           0 : PluginInstanceParent::UnregisterNPObject(NPObject* aObject)
    1868             : {
    1869           0 :     NS_ASSERTION(aObject, "Null pointer!");
    1870           0 :     NS_ASSERTION(mScriptableObjects.Get(aObject, nullptr), "Unknown entry!");
    1871           0 :     mScriptableObjects.Remove(aObject);
    1872           0 : }
    1873             : 
    1874             : PluginScriptableObjectParent*
    1875           0 : PluginInstanceParent::GetActorForNPObject(NPObject* aObject)
    1876             : {
    1877           0 :     NS_ASSERTION(aObject, "Null pointer!");
    1878             : 
    1879           0 :     if (aObject->_class == PluginScriptableObjectParent::GetClass()) {
    1880             :         // One of ours!
    1881           0 :         ParentNPObject* object = static_cast<ParentNPObject*>(aObject);
    1882           0 :         NS_ASSERTION(object->parent, "Null actor!");
    1883           0 :         return object->parent;
    1884             :     }
    1885             : 
    1886             :     PluginScriptableObjectParent* actor;
    1887           0 :     if (mScriptableObjects.Get(aObject, &actor)) {
    1888           0 :         return actor;
    1889             :     }
    1890             : 
    1891           0 :     actor = new PluginScriptableObjectParent(LocalObject);
    1892           0 :     if (!SendPPluginScriptableObjectConstructor(actor)) {
    1893           0 :         NS_WARNING("Failed to send constructor message!");
    1894           0 :         return nullptr;
    1895             :     }
    1896             : 
    1897           0 :     actor->InitializeLocal(aObject);
    1898           0 :     return actor;
    1899             : }
    1900             : 
    1901             : PPluginSurfaceParent*
    1902           0 : PluginInstanceParent::AllocPPluginSurfaceParent(const WindowsSharedMemoryHandle& handle,
    1903             :                                                 const mozilla::gfx::IntSize& size,
    1904             :                                                 const bool& transparent)
    1905             : {
    1906             : #ifdef XP_WIN
    1907             :     return new PluginSurfaceParent(handle, size, transparent);
    1908             : #else
    1909           0 :     NS_ERROR("This shouldn't be called!");
    1910           0 :     return nullptr;
    1911             : #endif
    1912             : }
    1913             : 
    1914             : bool
    1915           0 : PluginInstanceParent::DeallocPPluginSurfaceParent(PPluginSurfaceParent* s)
    1916             : {
    1917             : #ifdef XP_WIN
    1918             :     delete s;
    1919             :     return true;
    1920             : #else
    1921           0 :     return false;
    1922             : #endif
    1923             : }
    1924             : 
    1925             : mozilla::ipc::IPCResult
    1926           0 : PluginInstanceParent::AnswerNPN_PushPopupsEnabledState(const bool& aState)
    1927             : {
    1928           0 :     mNPNIface->pushpopupsenabledstate(mNPP, aState ? 1 : 0);
    1929           0 :     return IPC_OK();
    1930             : }
    1931             : 
    1932             : mozilla::ipc::IPCResult
    1933           0 : PluginInstanceParent::AnswerNPN_PopPopupsEnabledState()
    1934             : {
    1935           0 :     mNPNIface->poppopupsenabledstate(mNPP);
    1936           0 :     return IPC_OK();
    1937             : }
    1938             : 
    1939             : mozilla::ipc::IPCResult
    1940           0 : PluginInstanceParent::AnswerNPN_GetValueForURL(const NPNURLVariable& variable,
    1941             :                                                const nsCString& url,
    1942             :                                                nsCString* value,
    1943             :                                                NPError* result)
    1944             : {
    1945             :     char* v;
    1946             :     uint32_t len;
    1947             : 
    1948           0 :     *result = mNPNIface->getvalueforurl(mNPP, (NPNURLVariable) variable,
    1949             :                                         url.get(), &v, &len);
    1950           0 :     if (NPERR_NO_ERROR == *result)
    1951           0 :         value->Adopt(v, len);
    1952             : 
    1953           0 :     return IPC_OK();
    1954             : }
    1955             : 
    1956             : mozilla::ipc::IPCResult
    1957           0 : PluginInstanceParent::AnswerNPN_SetValueForURL(const NPNURLVariable& variable,
    1958             :                                                const nsCString& url,
    1959             :                                                const nsCString& value,
    1960             :                                                NPError* result)
    1961             : {
    1962           0 :     *result = mNPNIface->setvalueforurl(mNPP, (NPNURLVariable) variable,
    1963             :                                         url.get(), value.get(),
    1964             :                                         value.Length());
    1965           0 :     return IPC_OK();
    1966             : }
    1967             : 
    1968             : mozilla::ipc::IPCResult
    1969           0 : PluginInstanceParent::AnswerNPN_ConvertPoint(const double& sourceX,
    1970             :                                              const bool&   ignoreDestX,
    1971             :                                              const double& sourceY,
    1972             :                                              const bool&   ignoreDestY,
    1973             :                                              const NPCoordinateSpace& sourceSpace,
    1974             :                                              const NPCoordinateSpace& destSpace,
    1975             :                                              double *destX,
    1976             :                                              double *destY,
    1977             :                                              bool *result)
    1978             : {
    1979           0 :     *result = mNPNIface->convertpoint(mNPP, sourceX, sourceY, sourceSpace,
    1980           0 :                                       ignoreDestX ? nullptr : destX,
    1981           0 :                                       ignoreDestY ? nullptr : destY,
    1982           0 :                                       destSpace);
    1983             : 
    1984           0 :     return IPC_OK();
    1985             : }
    1986             : 
    1987             : mozilla::ipc::IPCResult
    1988           0 : PluginInstanceParent::RecvRedrawPlugin()
    1989             : {
    1990           0 :     nsNPAPIPluginInstance *inst = static_cast<nsNPAPIPluginInstance*>(mNPP->ndata);
    1991           0 :     if (!inst) {
    1992           0 :         return IPC_FAIL_NO_REASON(this);
    1993             :     }
    1994             : 
    1995           0 :     inst->RedrawPlugin();
    1996           0 :     return IPC_OK();
    1997             : }
    1998             : 
    1999             : nsPluginInstanceOwner*
    2000           0 : PluginInstanceParent::GetOwner()
    2001             : {
    2002           0 :     nsNPAPIPluginInstance* inst = static_cast<nsNPAPIPluginInstance*>(mNPP->ndata);
    2003           0 :     if (!inst) {
    2004           0 :         return nullptr;
    2005             :     }
    2006           0 :     return inst->GetOwner();
    2007             : }
    2008             : 
    2009             : mozilla::ipc::IPCResult
    2010           0 : PluginInstanceParent::RecvSetNetscapeWindowAsParent(const NativeWindowHandle& childWindow)
    2011             : {
    2012             : #if defined(XP_WIN)
    2013             :     nsPluginInstanceOwner* owner = GetOwner();
    2014             :     if (!owner || NS_FAILED(owner->SetNetscapeWindowAsParent(childWindow))) {
    2015             :         NS_WARNING("Failed to set Netscape window as parent.");
    2016             :     }
    2017             : 
    2018             :     return IPC_OK();
    2019             : #else
    2020           0 :     NS_NOTREACHED("PluginInstanceParent::RecvSetNetscapeWindowAsParent not implemented!");
    2021           0 :     return IPC_FAIL_NO_REASON(this);
    2022             : #endif
    2023             : }
    2024             : 
    2025             : #if defined(OS_WIN)
    2026             : 
    2027             : /*
    2028             :   plugin focus changes between processes
    2029             : 
    2030             :   focus from dom -> child:
    2031             :     Focus manager calls on widget to set the focus on the window.
    2032             :     We pick up the resulting wm_setfocus event here, and forward
    2033             :     that over ipc to the child which calls set focus on itself.
    2034             : 
    2035             :   focus from child -> focus manager:
    2036             :     Child picks up the local wm_setfocus and sends it via ipc over
    2037             :     here. We then post a custom event to widget/windows/nswindow
    2038             :     which fires off a gui event letting the browser know.
    2039             : */
    2040             : 
    2041             : static const wchar_t kPluginInstanceParentProperty[] =
    2042             :                          L"PluginInstanceParentProperty";
    2043             : 
    2044             : // static
    2045             : LRESULT CALLBACK
    2046             : PluginInstanceParent::PluginWindowHookProc(HWND hWnd,
    2047             :                                            UINT message,
    2048             :                                            WPARAM wParam,
    2049             :                                            LPARAM lParam)
    2050             : {
    2051             :     PluginInstanceParent* self = reinterpret_cast<PluginInstanceParent*>(
    2052             :         ::GetPropW(hWnd, kPluginInstanceParentProperty));
    2053             :     if (!self) {
    2054             :         NS_NOTREACHED("PluginInstanceParent::PluginWindowHookProc null this ptr!");
    2055             :         return DefWindowProc(hWnd, message, wParam, lParam);
    2056             :     }
    2057             : 
    2058             :     NS_ASSERTION(self->mPluginHWND == hWnd, "Wrong window!");
    2059             : 
    2060             :     switch (message) {
    2061             :         case WM_SETFOCUS:
    2062             :         // Let the child plugin window know it should take focus.
    2063             :         Unused << self->CallSetPluginFocus();
    2064             :         break;
    2065             : 
    2066             :         case WM_CLOSE:
    2067             :         self->UnsubclassPluginWindow();
    2068             :         break;
    2069             :     }
    2070             : 
    2071             :     if (self->mPluginWndProc == PluginWindowHookProc) {
    2072             :       NS_NOTREACHED(
    2073             :         "PluginWindowHookProc invoking mPluginWndProc w/"
    2074             :         "mPluginWndProc == PluginWindowHookProc????");
    2075             :         return DefWindowProc(hWnd, message, wParam, lParam);
    2076             :     }
    2077             :     return ::CallWindowProc(self->mPluginWndProc, hWnd, message, wParam,
    2078             :                             lParam);
    2079             : }
    2080             : 
    2081             : void
    2082             : PluginInstanceParent::SubclassPluginWindow(HWND aWnd)
    2083             : {
    2084             :     if ((aWnd && mPluginHWND == aWnd) || (!aWnd && mPluginHWND)) {
    2085             :         return;
    2086             :     }
    2087             : 
    2088             :     if (XRE_IsContentProcess()) {
    2089             :         if (!aWnd) {
    2090             :             NS_WARNING("PluginInstanceParent::SubclassPluginWindow unexpected null window");
    2091             :             return;
    2092             :         }
    2093             :         mPluginHWND = aWnd; // now a remote window, we can't subclass this
    2094             :         mPluginWndProc = nullptr;
    2095             :         // Note sPluginInstanceList wil delete 'this' if we do not remove
    2096             :         // it on shutdown.
    2097             :         sPluginInstanceList->Put((void*)mPluginHWND, this);
    2098             :         return;
    2099             :     }
    2100             : 
    2101             :     NS_ASSERTION(!(mPluginHWND && aWnd != mPluginHWND),
    2102             :         "PluginInstanceParent::SubclassPluginWindow hwnd is not our window!");
    2103             : 
    2104             :     mPluginHWND = aWnd;
    2105             :     mPluginWndProc =
    2106             :         (WNDPROC)::SetWindowLongPtrA(mPluginHWND, GWLP_WNDPROC,
    2107             :             reinterpret_cast<LONG_PTR>(PluginWindowHookProc));
    2108             :     DebugOnly<bool> bRes = ::SetPropW(mPluginHWND, kPluginInstanceParentProperty, this);
    2109             :     NS_ASSERTION(mPluginWndProc,
    2110             :         "PluginInstanceParent::SubclassPluginWindow failed to set subclass!");
    2111             :     NS_ASSERTION(bRes,
    2112             :         "PluginInstanceParent::SubclassPluginWindow failed to set prop!");
    2113             : }
    2114             : 
    2115             : void
    2116             : PluginInstanceParent::UnsubclassPluginWindow()
    2117             : {
    2118             :     if (XRE_IsContentProcess()) {
    2119             :         if (mPluginHWND) {
    2120             :             // Remove 'this' from the plugin list safely
    2121             :             nsAutoPtr<PluginInstanceParent> tmp;
    2122             :             MOZ_ASSERT(sPluginInstanceList);
    2123             :             sPluginInstanceList->Remove((void*)mPluginHWND, &tmp);
    2124             :             tmp.forget();
    2125             :             if (!sPluginInstanceList->Count()) {
    2126             :                 delete sPluginInstanceList;
    2127             :                 sPluginInstanceList = nullptr;
    2128             :             }
    2129             :         }
    2130             :         mPluginHWND = nullptr;
    2131             :         return;
    2132             :     }
    2133             : 
    2134             :     if (mPluginHWND && mPluginWndProc) {
    2135             :         ::SetWindowLongPtrA(mPluginHWND, GWLP_WNDPROC,
    2136             :                             reinterpret_cast<LONG_PTR>(mPluginWndProc));
    2137             : 
    2138             :         ::RemovePropW(mPluginHWND, kPluginInstanceParentProperty);
    2139             : 
    2140             :         mPluginWndProc = nullptr;
    2141             :         mPluginHWND = nullptr;
    2142             :     }
    2143             : }
    2144             : 
    2145             : /* windowless drawing helpers */
    2146             : 
    2147             : /*
    2148             :  * Origin info:
    2149             :  *
    2150             :  * windowless, offscreen:
    2151             :  *
    2152             :  * WM_WINDOWPOSCHANGED: origin is relative to container
    2153             :  * setwindow: origin is 0,0
    2154             :  * WM_PAINT: origin is 0,0
    2155             :  *
    2156             :  * windowless, native:
    2157             :  *
    2158             :  * WM_WINDOWPOSCHANGED: origin is relative to container
    2159             :  * setwindow: origin is relative to container
    2160             :  * WM_PAINT: origin is relative to container
    2161             :  *
    2162             :  * PluginInstanceParent:
    2163             :  *
    2164             :  * painting: mPluginPort (nsIntRect, saved in SetWindow)
    2165             :  */
    2166             : 
    2167             : bool
    2168             : PluginInstanceParent::MaybeCreateAndParentChildPluginWindow()
    2169             : {
    2170             :     // On Windows we need to create and set the parent before we set the
    2171             :     // window on the plugin, or keyboard interaction will not work.
    2172             :     if (!mChildPluginHWND) {
    2173             :         if (!CallCreateChildPluginWindow(&mChildPluginHWND) ||
    2174             :             !mChildPluginHWND) {
    2175             :             return false;
    2176             :         }
    2177             :     }
    2178             : 
    2179             :     // It's not clear if the parent window would ever change, but when this
    2180             :     // was done in the NPAPI child it used to allow for this.
    2181             :     if (mPluginHWND == mChildPluginsParentHWND) {
    2182             :         return true;
    2183             :     }
    2184             : 
    2185             :     nsPluginInstanceOwner* owner = GetOwner();
    2186             :     if (!owner) {
    2187             :         // We can't reparent without an owner, the plugin is probably shutting
    2188             :         // down, just return true to allow any calls to continue.
    2189             :         return true;
    2190             :     }
    2191             : 
    2192             :     // Note that this call will probably cause a sync native message to the
    2193             :     // process that owns the child window.
    2194             :     owner->SetWidgetWindowAsParent(mChildPluginHWND);
    2195             :     mChildPluginsParentHWND = mPluginHWND;
    2196             :     return true;
    2197             : }
    2198             : 
    2199             : void
    2200             : PluginInstanceParent::MaybeCreateChildPopupSurrogate()
    2201             : {
    2202             :     // Already created or not required for this plugin.
    2203             :     if (mChildPluginHWND || mWindowType != NPWindowTypeDrawable ||
    2204             :         !(mParent->GetQuirks() & QUIRK_WINLESS_TRACKPOPUP_HOOK)) {
    2205             :         return;
    2206             :     }
    2207             : 
    2208             :     // We need to pass the netscape window down to be cached as part of the call
    2209             :     // to create the surrogate, because the reparenting of the surrogate in the
    2210             :     // main process can cause sync Windows messages to the plugin process, which
    2211             :     // then cause sync messages from the plugin child for the netscape window
    2212             :     // which causes a deadlock.
    2213             :     NativeWindowHandle netscapeWindow;
    2214             :     NPError result = mNPNIface->getvalue(mNPP, NPNVnetscapeWindow,
    2215             :                                          &netscapeWindow);
    2216             :     if (NPERR_NO_ERROR != result) {
    2217             :         NS_WARNING("Can't get netscape window to pass to plugin child.");
    2218             :         return;
    2219             :     }
    2220             : 
    2221             :     if (!SendCreateChildPopupSurrogate(netscapeWindow)) {
    2222             :         NS_WARNING("Failed to create popup surrogate in child.");
    2223             :     }
    2224             : }
    2225             : 
    2226             : #endif // defined(OS_WIN)
    2227             : 
    2228             : mozilla::ipc::IPCResult
    2229           0 : PluginInstanceParent::AnswerPluginFocusChange(const bool& gotFocus)
    2230             : {
    2231           0 :     PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
    2232             : 
    2233             :     // Currently only in use on windows - an event we receive from the child
    2234             :     // when it's plugin window (or one of it's children) receives keyboard
    2235             :     // focus. We detect this and forward a notification here so we can update
    2236             :     // focus.
    2237             : #if defined(OS_WIN)
    2238             :     if (gotFocus) {
    2239             :       nsPluginInstanceOwner* owner = GetOwner();
    2240             :       if (owner) {
    2241             :         nsIFocusManager* fm = nsFocusManager::GetFocusManager();
    2242             :         nsCOMPtr<nsIDOMElement> element;
    2243             :         owner->GetDOMElement(getter_AddRefs(element));
    2244             :         if (fm && element) {
    2245             :           fm->SetFocus(element, 0);
    2246             :         }
    2247             :       }
    2248             :     }
    2249             :     return IPC_OK();
    2250             : #else
    2251           0 :     NS_NOTREACHED("PluginInstanceParent::AnswerPluginFocusChange not implemented!");
    2252           0 :     return IPC_FAIL_NO_REASON(this);
    2253             : #endif
    2254             : }
    2255             : 
    2256             : PluginInstanceParent*
    2257           0 : PluginInstanceParent::Cast(NPP aInstance)
    2258             : {
    2259           0 :     auto ip = static_cast<PluginInstanceParent*>(aInstance->pdata);
    2260             : 
    2261             :     // If the plugin crashed and the PluginInstanceParent was deleted,
    2262             :     // aInstance->pdata will be nullptr.
    2263           0 :     if (!ip) {
    2264           0 :         return nullptr;
    2265             :     }
    2266             : 
    2267           0 :     if (aInstance != ip->mNPP) {
    2268           0 :         MOZ_CRASH("Corrupted plugin data.");
    2269             :     }
    2270             : 
    2271           0 :     return ip;
    2272             : }
    2273             : 
    2274             : mozilla::ipc::IPCResult
    2275           0 : PluginInstanceParent::RecvGetCompositionString(const uint32_t& aIndex,
    2276             :                                                nsTArray<uint8_t>* aDist,
    2277             :                                                int32_t* aLength)
    2278             : {
    2279             : #if defined(OS_WIN)
    2280             :     nsPluginInstanceOwner* owner = GetOwner();
    2281             :     if (!owner) {
    2282             :         *aLength = IMM_ERROR_GENERAL;
    2283             :         return IPC_OK();
    2284             :     }
    2285             : 
    2286             :     if (!owner->GetCompositionString(aIndex, aDist, aLength)) {
    2287             :         *aLength = IMM_ERROR_NODATA;
    2288             :     }
    2289             : #endif
    2290           0 :     return IPC_OK();
    2291             : }
    2292             : 
    2293             : mozilla::ipc::IPCResult
    2294           0 : PluginInstanceParent::RecvSetCandidateWindow(
    2295             :     const mozilla::widget::CandidateWindowPosition& aPosition)
    2296             : {
    2297             : #if defined(OS_WIN)
    2298             :     nsPluginInstanceOwner* owner = GetOwner();
    2299             :     if (owner) {
    2300             :         owner->SetCandidateWindow(aPosition);
    2301             :     }
    2302             : #endif
    2303           0 :     return IPC_OK();
    2304             : }
    2305             : 
    2306             : mozilla::ipc::IPCResult
    2307           0 : PluginInstanceParent::RecvRequestCommitOrCancel(const bool& aCommitted)
    2308             : {
    2309             : #if defined(OS_WIN)
    2310             :     nsPluginInstanceOwner* owner = GetOwner();
    2311             :     if (owner) {
    2312             :         owner->RequestCommitOrCancel(aCommitted);
    2313             :     }
    2314             : #endif
    2315           0 :     return IPC_OK();
    2316             : }
    2317             : 
    2318             : nsresult
    2319           0 : PluginInstanceParent::HandledWindowedPluginKeyEvent(
    2320             :                         const NativeEventData& aKeyEventData,
    2321             :                         bool aIsConsumed)
    2322             : {
    2323           0 :     if (NS_WARN_IF(!SendHandledWindowedPluginKeyEvent(aKeyEventData,
    2324             :                                                       aIsConsumed))) {
    2325           0 :         return NS_ERROR_FAILURE;
    2326             :     }
    2327           0 :     return NS_OK;
    2328             : }
    2329             : 
    2330             : mozilla::ipc::IPCResult
    2331           0 : PluginInstanceParent::RecvOnWindowedPluginKeyEvent(
    2332             :                         const NativeEventData& aKeyEventData)
    2333             : {
    2334           0 :     nsPluginInstanceOwner* owner = GetOwner();
    2335           0 :     if (NS_WARN_IF(!owner)) {
    2336             :         // Notifies the plugin process of the key event being not consumed
    2337             :         // by us.
    2338           0 :         HandledWindowedPluginKeyEvent(aKeyEventData, false);
    2339           0 :         return IPC_OK();
    2340             :     }
    2341           0 :     owner->OnWindowedPluginKeyEvent(aKeyEventData);
    2342           0 :     return IPC_OK();
    2343             : }
    2344             : 
    2345             : void
    2346           0 : PluginInstanceParent::RecordDrawingModel()
    2347             : {
    2348           0 :     int mode = -1;
    2349           0 :     switch (mWindowType) {
    2350             :     case NPWindowTypeWindow:
    2351             :         // We use 0=windowed since there is no specific NPDrawingModel value.
    2352           0 :         mode = 0;
    2353           0 :         break;
    2354             :     case NPWindowTypeDrawable:
    2355           0 :         mode = mDrawingModel + 1;
    2356           0 :         break;
    2357             :     default:
    2358           0 :         MOZ_ASSERT_UNREACHABLE("bad window type");
    2359             :         return;
    2360             :     }
    2361             : 
    2362           0 :     if (mode == mLastRecordedDrawingModel) {
    2363           0 :         return;
    2364             :     }
    2365           0 :     MOZ_ASSERT(mode >= 0);
    2366             : 
    2367           0 :     Telemetry::Accumulate(Telemetry::PLUGIN_DRAWING_MODEL, mode);
    2368           0 :     mLastRecordedDrawingModel = mode;
    2369             : }

Generated by: LCOV version 1.13