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

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #include "mozilla/DebugOnly.h"
       7             : 
       8             : #ifdef MOZ_WIDGET_ANDROID
       9             : // For ScreenOrientation.h and Hal.h
      10             : #include "base/basictypes.h"
      11             : #endif
      12             : 
      13             : #include "mozilla/Logging.h"
      14             : #include "nscore.h"
      15             : #include "prenv.h"
      16             : 
      17             : #include "nsNPAPIPluginInstance.h"
      18             : #include "nsNPAPIPlugin.h"
      19             : #include "nsNPAPIPluginStreamListener.h"
      20             : #include "nsPluginHost.h"
      21             : #include "nsPluginLogging.h"
      22             : #include "nsContentUtils.h"
      23             : #include "nsPluginInstanceOwner.h"
      24             : 
      25             : #include "nsThreadUtils.h"
      26             : #include "nsIDOMElement.h"
      27             : #include "nsIDocument.h"
      28             : #include "nsIDocShell.h"
      29             : #include "nsIScriptGlobalObject.h"
      30             : #include "nsIScriptContext.h"
      31             : #include "nsDirectoryServiceDefs.h"
      32             : #include "nsJSNPRuntime.h"
      33             : #include "nsPluginStreamListenerPeer.h"
      34             : #include "nsSize.h"
      35             : #include "nsNetCID.h"
      36             : #include "nsIContent.h"
      37             : #include "nsVersionComparator.h"
      38             : #include "mozilla/Preferences.h"
      39             : #include "mozilla/Unused.h"
      40             : #include "nsILoadContext.h"
      41             : #include "mozilla/dom/HTMLObjectElementBinding.h"
      42             : #include "AudioChannelService.h"
      43             : 
      44             : using namespace mozilla;
      45             : using namespace mozilla::dom;
      46             : 
      47             : #ifdef MOZ_WIDGET_ANDROID
      48             : #include "ANPBase.h"
      49             : #include <android/log.h>
      50             : #include "android_npapi.h"
      51             : #include "mozilla/Mutex.h"
      52             : #include "mozilla/CondVar.h"
      53             : #include "mozilla/dom/ScreenOrientation.h"
      54             : #include "mozilla/Hal.h"
      55             : #include "GLContextProvider.h"
      56             : #include "GLContext.h"
      57             : #include "TexturePoolOGL.h"
      58             : #include "SurfaceTypes.h"
      59             : #include "EGLUtils.h"
      60             : #include "GeneratedJNIWrappers.h"
      61             : #include "GeneratedJNINatives.h"
      62             : 
      63             : using namespace mozilla;
      64             : using namespace mozilla::gl;
      65             : 
      66             : typedef nsNPAPIPluginInstance::VideoInfo VideoInfo;
      67             : 
      68             : class PluginEventRunnable : public Runnable
      69             : {
      70             : public:
      71             :   PluginEventRunnable(nsNPAPIPluginInstance* instance, ANPEvent* event)
      72             :     : Runnable("PluginEventRunnable"),
      73             :       mInstance(instance),
      74             :       mEvent(*event),
      75             :       mCanceled(false)
      76             :   {
      77             :   }
      78             : 
      79             :   virtual nsresult Run() {
      80             :     if (mCanceled)
      81             :       return NS_OK;
      82             : 
      83             :     mInstance->HandleEvent(&mEvent, nullptr);
      84             :     mInstance->PopPostedEvent(this);
      85             :     return NS_OK;
      86             :   }
      87             : 
      88             :   void Cancel() { mCanceled = true; }
      89             : private:
      90             :   nsNPAPIPluginInstance* mInstance;
      91             :   ANPEvent mEvent;
      92             :   bool mCanceled;
      93             : };
      94             : 
      95             : static RefPtr<GLContext> sPluginContext = nullptr;
      96             : 
      97             : static bool EnsureGLContext()
      98             : {
      99             :   if (!sPluginContext) {
     100             :     const auto flags = CreateContextFlags::REQUIRE_COMPAT_PROFILE;
     101             :     nsCString discardedFailureId;
     102             :     sPluginContext = GLContextProvider::CreateHeadless(flags, &discardedFailureId);
     103             :   }
     104             : 
     105             :   return sPluginContext != nullptr;
     106             : }
     107             : 
     108             : static std::map<NPP, nsNPAPIPluginInstance*> sPluginNPPMap;
     109             : 
     110             : #endif // MOZ_WIDGET_ANDROID
     111             : 
     112             : using namespace mozilla;
     113             : using namespace mozilla::plugins::parent;
     114             : using namespace mozilla::layers;
     115             : 
     116             : static NS_DEFINE_IID(kIOutputStreamIID, NS_IOUTPUTSTREAM_IID);
     117             : 
     118           0 : NS_IMPL_ISUPPORTS(nsNPAPIPluginInstance, nsIAudioChannelAgentCallback)
     119             : 
     120           0 : nsNPAPIPluginInstance::nsNPAPIPluginInstance()
     121             :   : mDrawingModel(kDefaultDrawingModel)
     122             : #ifdef MOZ_WIDGET_ANDROID
     123             :   , mANPDrawingModel(0)
     124             :   , mFullScreenOrientation(dom::eScreenOrientation_LandscapePrimary)
     125             :   , mWakeLocked(false)
     126             :   , mFullScreen(false)
     127             :   , mOriginPos(gl::OriginPos::TopLeft)
     128             : #endif
     129             :   , mRunning(NOT_STARTED)
     130             :   , mWindowless(false)
     131             :   , mTransparent(false)
     132             :   , mCached(false)
     133             :   , mUsesDOMForCursor(false)
     134             :   , mInPluginInitCall(false)
     135             :   , mPlugin(nullptr)
     136             :   , mMIMEType(nullptr)
     137             :   , mOwner(nullptr)
     138             : #ifdef XP_MACOSX
     139             :   , mCurrentPluginEvent(nullptr)
     140             : #endif
     141             : #ifdef MOZ_WIDGET_ANDROID
     142             :   , mOnScreen(true)
     143             : #endif
     144             :   , mHaveJavaC2PJSObjectQuirk(false)
     145             :   , mCachedParamLength(0)
     146             :   , mCachedParamNames(nullptr)
     147             :   , mCachedParamValues(nullptr)
     148           0 :   , mMuted(false)
     149             : {
     150           0 :   mNPP.pdata = nullptr;
     151           0 :   mNPP.ndata = this;
     152             : 
     153           0 :   PLUGIN_LOG(PLUGIN_LOG_BASIC, ("nsNPAPIPluginInstance ctor: this=%p\n",this));
     154             : 
     155             : #ifdef MOZ_WIDGET_ANDROID
     156             :   sPluginNPPMap[&mNPP] = this;
     157             : #endif
     158           0 : }
     159             : 
     160           0 : nsNPAPIPluginInstance::~nsNPAPIPluginInstance()
     161             : {
     162           0 :   PLUGIN_LOG(PLUGIN_LOG_BASIC, ("nsNPAPIPluginInstance dtor: this=%p\n",this));
     163             : 
     164             : #ifdef MOZ_WIDGET_ANDROID
     165             :   sPluginNPPMap.erase(&mNPP);
     166             : #endif
     167             : 
     168           0 :   if (mMIMEType) {
     169           0 :     free(mMIMEType);
     170           0 :     mMIMEType = nullptr;
     171             :   }
     172             : 
     173           0 :   if (!mCachedParamValues || !mCachedParamNames) {
     174             :     return;
     175             :   }
     176           0 :   MOZ_ASSERT(mCachedParamValues && mCachedParamNames);
     177             : 
     178           0 :   for (uint32_t i = 0; i < mCachedParamLength; i++) {
     179           0 :     if (mCachedParamNames[i]) {
     180           0 :       free(mCachedParamNames[i]);
     181           0 :       mCachedParamNames[i] = nullptr;
     182             :     }
     183           0 :     if (mCachedParamValues[i]) {
     184           0 :       free(mCachedParamValues[i]);
     185           0 :       mCachedParamValues[i] = nullptr;
     186             :     }
     187             :   }
     188             : 
     189           0 :   free(mCachedParamNames);
     190           0 :   mCachedParamNames = nullptr;
     191             : 
     192           0 :   free(mCachedParamValues);
     193           0 :   mCachedParamValues = nullptr;
     194           0 : }
     195             : 
     196             : uint32_t nsNPAPIPluginInstance::gInUnsafePluginCalls = 0;
     197             : 
     198             : void
     199           0 : nsNPAPIPluginInstance::Destroy()
     200             : {
     201           0 :   Stop();
     202           0 :   mPlugin = nullptr;
     203           0 :   mAudioChannelAgent = nullptr;
     204             : 
     205             : #if MOZ_WIDGET_ANDROID
     206             :   if (mContentSurface) {
     207             :     java::SurfaceAllocator::DisposeSurface(mContentSurface);
     208             :   }
     209             : 
     210             :   std::map<void*, VideoInfo*>::iterator it;
     211             :   for (it = mVideos.begin(); it != mVideos.end(); it++) {
     212             :     delete it->second;
     213             :   }
     214             :   mVideos.clear();
     215             :   SetWakeLock(false);
     216             : #endif
     217           0 : }
     218             : 
     219             : TimeStamp
     220           0 : nsNPAPIPluginInstance::StopTime()
     221             : {
     222           0 :   return mStopTime;
     223             : }
     224             : 
     225           0 : nsresult nsNPAPIPluginInstance::Initialize(nsNPAPIPlugin *aPlugin, nsPluginInstanceOwner* aOwner, const nsACString& aMIMEType)
     226             : {
     227           0 :   AUTO_PROFILER_LABEL("nsNPAPIPlugin::Initialize", OTHER);
     228           0 :   PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance::Initialize this=%p\n",this));
     229             : 
     230           0 :   NS_ENSURE_ARG_POINTER(aPlugin);
     231           0 :   NS_ENSURE_ARG_POINTER(aOwner);
     232             : 
     233           0 :   mPlugin = aPlugin;
     234           0 :   mOwner = aOwner;
     235             : 
     236           0 :   if (!aMIMEType.IsEmpty()) {
     237           0 :     mMIMEType = ToNewCString(aMIMEType);
     238             :   }
     239             : 
     240           0 :   return Start();
     241             : }
     242             : 
     243           0 : nsresult nsNPAPIPluginInstance::Stop()
     244             : {
     245           0 :   PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance::Stop this=%p\n",this));
     246             : 
     247             :   // Make sure the plugin didn't leave popups enabled.
     248           0 :   if (mPopupStates.Length() > 0) {
     249           0 :     nsCOMPtr<nsPIDOMWindowOuter> window = GetDOMWindow();
     250             : 
     251           0 :     if (window) {
     252           0 :       window->PopPopupControlState(openAbused);
     253             :     }
     254             :   }
     255             : 
     256           0 :   if (RUNNING != mRunning) {
     257           0 :     return NS_OK;
     258             :   }
     259             : 
     260             :   // clean up all outstanding timers
     261           0 :   for (uint32_t i = mTimers.Length(); i > 0; i--)
     262           0 :     UnscheduleTimer(mTimers[i - 1]->id);
     263             : 
     264             :   // If there's code from this plugin instance on the stack, delay the
     265             :   // destroy.
     266           0 :   if (PluginDestructionGuard::DelayDestroy(this)) {
     267           0 :     return NS_OK;
     268             :   }
     269             : 
     270             :   // Make sure we lock while we're writing to mRunning after we've
     271             :   // started as other threads might be checking that inside a lock.
     272             :   {
     273           0 :     AsyncCallbackAutoLock lock;
     274           0 :     mRunning = DESTROYING;
     275           0 :     mStopTime = TimeStamp::Now();
     276             :   }
     277             : 
     278           0 :   OnPluginDestroy(&mNPP);
     279             : 
     280             :   // clean up open streams
     281           0 :   while (mStreamListeners.Length() > 0) {
     282           0 :     RefPtr<nsNPAPIPluginStreamListener> currentListener(mStreamListeners[0]);
     283           0 :     currentListener->CleanUpStream(NPRES_USER_BREAK);
     284           0 :     mStreamListeners.RemoveElement(currentListener);
     285             :   }
     286             : 
     287           0 :   if (!mPlugin || !mPlugin->GetLibrary())
     288           0 :     return NS_ERROR_FAILURE;
     289             : 
     290           0 :   NPPluginFuncs* pluginFunctions = mPlugin->PluginFuncs();
     291             : 
     292           0 :   NPError error = NPERR_GENERIC_ERROR;
     293           0 :   if (pluginFunctions->destroy) {
     294           0 :     NPSavedData *sdata = 0;
     295             : 
     296           0 :     NS_TRY_SAFE_CALL_RETURN(error, (*pluginFunctions->destroy)(&mNPP, &sdata), this,
     297             :                             NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO);
     298             : 
     299           0 :     NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
     300             :                    ("NPP Destroy called: this=%p, npp=%p, return=%d\n", this, &mNPP, error));
     301             :   }
     302           0 :   mRunning = DESTROYED;
     303             : 
     304             : #if MOZ_WIDGET_ANDROID
     305             :   for (uint32_t i = 0; i < mPostedEvents.Length(); i++) {
     306             :     mPostedEvents[i]->Cancel();
     307             :   }
     308             : 
     309             :   mPostedEvents.Clear();
     310             : #endif
     311             : 
     312           0 :   nsJSNPRuntime::OnPluginDestroy(&mNPP);
     313             : 
     314           0 :   if (error != NPERR_NO_ERROR)
     315           0 :     return NS_ERROR_FAILURE;
     316             :   else
     317           0 :     return NS_OK;
     318             : }
     319             : 
     320             : already_AddRefed<nsPIDOMWindowOuter>
     321           0 : nsNPAPIPluginInstance::GetDOMWindow()
     322             : {
     323           0 :   if (!mOwner)
     324           0 :     return nullptr;
     325             : 
     326           0 :   RefPtr<nsPluginInstanceOwner> kungFuDeathGrip(mOwner);
     327             : 
     328           0 :   nsCOMPtr<nsIDocument> doc;
     329           0 :   kungFuDeathGrip->GetDocument(getter_AddRefs(doc));
     330           0 :   if (!doc)
     331           0 :     return nullptr;
     332             : 
     333           0 :   RefPtr<nsPIDOMWindowOuter> window = doc->GetWindow();
     334             : 
     335           0 :   return window.forget();
     336             : }
     337             : 
     338             : nsresult
     339           0 : nsNPAPIPluginInstance::GetTagType(nsPluginTagType *result)
     340             : {
     341           0 :   if (!mOwner) {
     342           0 :     return NS_ERROR_FAILURE;
     343             :   }
     344             : 
     345           0 :   return mOwner->GetTagType(result);
     346             : }
     347             : 
     348             : nsTArray<nsNPAPIPluginStreamListener*>*
     349           0 : nsNPAPIPluginInstance::StreamListeners()
     350             : {
     351           0 :   return &mStreamListeners;
     352             : }
     353             : 
     354             : nsTArray<nsPluginStreamListenerPeer*>*
     355           0 : nsNPAPIPluginInstance::FileCachedStreamListeners()
     356             : {
     357           0 :   return &mFileCachedStreamListeners;
     358             : }
     359             : 
     360             : nsresult
     361           0 : nsNPAPIPluginInstance::Start()
     362             : {
     363           0 :   if (mRunning == RUNNING) {
     364           0 :     return NS_OK;
     365             :   }
     366             : 
     367           0 :   if (!mOwner) {
     368           0 :     MOZ_ASSERT(false, "Should not be calling Start() on unowned plugin.");
     369             :     return NS_ERROR_FAILURE;
     370             :   }
     371             : 
     372           0 :   PluginDestructionGuard guard(this);
     373             : 
     374           0 :   nsTArray<MozPluginParameter> attributes;
     375           0 :   nsTArray<MozPluginParameter> params;
     376             : 
     377             :   nsPluginTagType tagtype;
     378           0 :   nsresult rv = GetTagType(&tagtype);
     379           0 :   if (NS_SUCCEEDED(rv)) {
     380           0 :     mOwner->GetAttributes(attributes);
     381           0 :     mOwner->GetParameters(params);
     382             :   } else {
     383           0 :     MOZ_ASSERT(false, "Failed to get tag type.");
     384             :   }
     385             : 
     386           0 :   mCachedParamLength = attributes.Length() + 1 + params.Length();
     387             : 
     388             :   // We add an extra entry "PARAM" as a separator between the attribute
     389             :   // and param values, but we don't count it if there are no <param> entries.
     390             :   // Legacy behavior quirk.
     391           0 :   uint32_t quirkParamLength = params.Length() ?
     392           0 :                                 mCachedParamLength : attributes.Length();
     393             : 
     394           0 :   mCachedParamNames = (char**)moz_xmalloc(sizeof(char*) * mCachedParamLength);
     395           0 :   mCachedParamValues = (char**)moz_xmalloc(sizeof(char*) * mCachedParamLength);
     396             : 
     397           0 :   for (uint32_t i = 0; i < attributes.Length(); i++) {
     398           0 :     mCachedParamNames[i] = ToNewUTF8String(attributes[i].mName);
     399           0 :     mCachedParamValues[i] = ToNewUTF8String(attributes[i].mValue);
     400             :   }
     401             : 
     402             :   // Android expects and empty string instead of null.
     403           0 :   mCachedParamNames[attributes.Length()] = ToNewUTF8String(NS_LITERAL_STRING("PARAM"));
     404             :   #ifdef MOZ_WIDGET_ANDROID
     405             :     mCachedParamValues[attributes.Length()] = ToNewUTF8String(NS_LITERAL_STRING(""));
     406             :   #else
     407           0 :     mCachedParamValues[attributes.Length()] = nullptr;
     408             :   #endif
     409             : 
     410           0 :   for (uint32_t i = 0, pos = attributes.Length() + 1; i < params.Length(); i ++) {
     411           0 :     mCachedParamNames[pos] = ToNewUTF8String(params[i].mName);
     412           0 :     mCachedParamValues[pos] = ToNewUTF8String(params[i].mValue);
     413           0 :     pos++;
     414             :   }
     415             : 
     416             :   const char*   mimetype;
     417           0 :   NPError       error = NPERR_GENERIC_ERROR;
     418             : 
     419           0 :   GetMIMEType(&mimetype);
     420             : 
     421           0 :   CheckJavaC2PJSObjectQuirk(quirkParamLength, mCachedParamNames, mCachedParamValues);
     422             : 
     423           0 :   bool oldVal = mInPluginInitCall;
     424           0 :   mInPluginInitCall = true;
     425             : 
     426             :   // Need this on the stack before calling NPP_New otherwise some callbacks that
     427             :   // the plugin may make could fail (NPN_HasProperty, for example).
     428           0 :   NPPAutoPusher autopush(&mNPP);
     429             : 
     430           0 :   if (!mPlugin)
     431           0 :     return NS_ERROR_FAILURE;
     432             : 
     433           0 :   PluginLibrary* library = mPlugin->GetLibrary();
     434           0 :   if (!library)
     435           0 :     return NS_ERROR_FAILURE;
     436             : 
     437             :   // Mark this instance as running before calling NPP_New because the plugin may
     438             :   // call other NPAPI functions, like NPN_GetURLNotify, that assume this is set
     439             :   // before returning. If the plugin returns failure, we'll clear it out below.
     440           0 :   mRunning = RUNNING;
     441             : 
     442           0 :   nsresult newResult = library->NPP_New((char*)mimetype, &mNPP,
     443             :                                         quirkParamLength, mCachedParamNames,
     444           0 :                                         mCachedParamValues, nullptr, &error);
     445           0 :   mInPluginInitCall = oldVal;
     446             : 
     447           0 :   NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
     448             :   ("NPP New called: this=%p, npp=%p, mime=%s, argc=%d, return=%d\n",
     449             :   this, &mNPP, mimetype, quirkParamLength, error));
     450             : 
     451           0 :   if (NS_FAILED(newResult) || error != NPERR_NO_ERROR) {
     452           0 :     mRunning = DESTROYED;
     453           0 :     nsJSNPRuntime::OnPluginDestroy(&mNPP);
     454           0 :     return NS_ERROR_FAILURE;
     455             :   }
     456             : 
     457           0 :   return newResult;
     458             : }
     459             : 
     460           0 : nsresult nsNPAPIPluginInstance::SetWindow(NPWindow* window)
     461             : {
     462             :   // NPAPI plugins don't want a SetWindow(nullptr).
     463           0 :   if (!window || RUNNING != mRunning)
     464           0 :     return NS_OK;
     465             : 
     466             : #if MOZ_WIDGET_GTK
     467             :   // bug 108347, flash plugin on linux doesn't like window->width <=
     468             :   // 0, but Java needs wants this call.
     469           0 :   if (window && window->type == NPWindowTypeWindow &&
     470           0 :       (window->width <= 0 || window->height <= 0) &&
     471           0 :       (nsPluginHost::GetSpecialType(nsDependentCString(mMIMEType)) !=
     472             :        nsPluginHost::eSpecialType_Java)) {
     473           0 :     return NS_OK;
     474             :   }
     475             : #endif
     476             : 
     477           0 :   if (!mPlugin || !mPlugin->GetLibrary())
     478           0 :     return NS_ERROR_FAILURE;
     479             : 
     480           0 :   NPPluginFuncs* pluginFunctions = mPlugin->PluginFuncs();
     481             : 
     482           0 :   if (pluginFunctions->setwindow) {
     483           0 :     PluginDestructionGuard guard(this);
     484             : 
     485             :     // XXX Turns out that NPPluginWindow and NPWindow are structurally
     486             :     // identical (on purpose!), so there's no need to make a copy.
     487             : 
     488           0 :     PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance::SetWindow (about to call it) this=%p\n",this));
     489             : 
     490           0 :     bool oldVal = mInPluginInitCall;
     491           0 :     mInPluginInitCall = true;
     492             : 
     493           0 :     NPPAutoPusher nppPusher(&mNPP);
     494             : 
     495             :     NPError error;
     496           0 :     NS_TRY_SAFE_CALL_RETURN(error, (*pluginFunctions->setwindow)(&mNPP, (NPWindow*)window), this,
     497             :                             NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO);
     498             :     // 'error' is only used if this is a logging-enabled build.
     499             :     // That is somewhat complex to check, so we just use "unused"
     500             :     // to suppress any compiler warnings in build configurations
     501             :     // where the logging is a no-op.
     502             :     mozilla::Unused << error;
     503             : 
     504           0 :     mInPluginInitCall = oldVal;
     505             : 
     506           0 :     NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
     507             :     ("NPP SetWindow called: this=%p, [x=%d,y=%d,w=%d,h=%d], clip[t=%d,b=%d,l=%d,r=%d], return=%d\n",
     508             :     this, window->x, window->y, window->width, window->height,
     509             :     window->clipRect.top, window->clipRect.bottom, window->clipRect.left, window->clipRect.right, error));
     510             :   }
     511           0 :   return NS_OK;
     512             : }
     513             : 
     514             : nsresult
     515           0 : nsNPAPIPluginInstance::NewStreamListener(const char* aURL, void* notifyData,
     516             :                                          nsNPAPIPluginStreamListener** listener)
     517             : {
     518           0 :   RefPtr<nsNPAPIPluginStreamListener> sl = new nsNPAPIPluginStreamListener(this, notifyData, aURL);
     519             : 
     520           0 :   mStreamListeners.AppendElement(sl);
     521             : 
     522           0 :   sl.forget(listener);
     523             : 
     524           0 :   return NS_OK;
     525             : }
     526             : 
     527           0 : nsresult nsNPAPIPluginInstance::Print(NPPrint* platformPrint)
     528             : {
     529           0 :   NS_ENSURE_TRUE(platformPrint, NS_ERROR_NULL_POINTER);
     530             : 
     531           0 :   PluginDestructionGuard guard(this);
     532             : 
     533           0 :   if (!mPlugin || !mPlugin->GetLibrary())
     534           0 :     return NS_ERROR_FAILURE;
     535             : 
     536           0 :   NPPluginFuncs* pluginFunctions = mPlugin->PluginFuncs();
     537             : 
     538           0 :   NPPrint* thePrint = (NPPrint *)platformPrint;
     539             : 
     540             :   // to be compatible with the older SDK versions and to match what
     541             :   // NPAPI and other browsers do, overwrite |window.type| field with one
     542             :   // more copy of |platformPrint|. See bug 113264
     543           0 :   uint16_t sdkmajorversion = (pluginFunctions->version & 0xff00)>>8;
     544           0 :   uint16_t sdkminorversion = pluginFunctions->version & 0x00ff;
     545           0 :   if ((sdkmajorversion == 0) && (sdkminorversion < 11)) {
     546             :     // Let's copy platformPrint bytes over to where it was supposed to be
     547             :     // in older versions -- four bytes towards the beginning of the struct
     548             :     // but we should be careful about possible misalignments
     549             :     if (sizeof(NPWindowType) >= sizeof(void *)) {
     550             :       void* source = thePrint->print.embedPrint.platformPrint;
     551             :       void** destination = (void **)&(thePrint->print.embedPrint.window.type);
     552             :       *destination = source;
     553             :     } else {
     554           0 :       NS_ERROR("Incompatible OS for assignment");
     555             :     }
     556             :   }
     557             : 
     558           0 :   if (pluginFunctions->print)
     559           0 :       NS_TRY_SAFE_CALL_VOID((*pluginFunctions->print)(&mNPP, thePrint), this,
     560             :                             NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO);
     561             : 
     562           0 :   NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
     563             :   ("NPP PrintProc called: this=%p, pDC=%p, [x=%d,y=%d,w=%d,h=%d], clip[t=%d,b=%d,l=%d,r=%d]\n",
     564             :   this,
     565             :   platformPrint->print.embedPrint.platformPrint,
     566             :   platformPrint->print.embedPrint.window.x,
     567             :   platformPrint->print.embedPrint.window.y,
     568             :   platformPrint->print.embedPrint.window.width,
     569             :   platformPrint->print.embedPrint.window.height,
     570             :   platformPrint->print.embedPrint.window.clipRect.top,
     571             :   platformPrint->print.embedPrint.window.clipRect.bottom,
     572             :   platformPrint->print.embedPrint.window.clipRect.left,
     573             :   platformPrint->print.embedPrint.window.clipRect.right));
     574             : 
     575           0 :   return NS_OK;
     576             : }
     577             : 
     578           0 : nsresult nsNPAPIPluginInstance::HandleEvent(void* event, int16_t* result,
     579             :                                             NSPluginCallReentry aSafeToReenterGecko)
     580             : {
     581           0 :   if (RUNNING != mRunning)
     582           0 :     return NS_OK;
     583             : 
     584           0 :   AUTO_PROFILER_LABEL("nsNPAPIPluginInstance::HandleEvent", OTHER);
     585             : 
     586           0 :   if (!event)
     587           0 :     return NS_ERROR_FAILURE;
     588             : 
     589           0 :   PluginDestructionGuard guard(this);
     590             : 
     591           0 :   if (!mPlugin || !mPlugin->GetLibrary())
     592           0 :     return NS_ERROR_FAILURE;
     593             : 
     594           0 :   NPPluginFuncs* pluginFunctions = mPlugin->PluginFuncs();
     595             : 
     596           0 :   int16_t tmpResult = kNPEventNotHandled;
     597             : 
     598           0 :   if (pluginFunctions->event) {
     599             : #ifdef XP_MACOSX
     600             :     mCurrentPluginEvent = event;
     601             : #endif
     602             : #if defined(XP_WIN)
     603             :     NS_TRY_SAFE_CALL_RETURN(tmpResult, (*pluginFunctions->event)(&mNPP, event), this,
     604             :                             aSafeToReenterGecko);
     605             : #else
     606             :     MAIN_THREAD_JNI_REF_GUARD;
     607           0 :     tmpResult = (*pluginFunctions->event)(&mNPP, event);
     608             : #endif
     609           0 :     NPP_PLUGIN_LOG(PLUGIN_LOG_NOISY,
     610             :       ("NPP HandleEvent called: this=%p, npp=%p, event=%p, return=%d\n",
     611             :       this, &mNPP, event, tmpResult));
     612             : 
     613           0 :     if (result)
     614           0 :       *result = tmpResult;
     615             : #ifdef XP_MACOSX
     616             :     mCurrentPluginEvent = nullptr;
     617             : #endif
     618             :   }
     619             : 
     620           0 :   return NS_OK;
     621             : }
     622             : 
     623           0 : nsresult nsNPAPIPluginInstance::GetValueFromPlugin(NPPVariable variable, void* value)
     624             : {
     625           0 :   if (!mPlugin || !mPlugin->GetLibrary())
     626           0 :     return NS_ERROR_FAILURE;
     627             : 
     628           0 :   NPPluginFuncs* pluginFunctions = mPlugin->PluginFuncs();
     629             : 
     630           0 :   nsresult rv = NS_ERROR_FAILURE;
     631             : 
     632           0 :   if (pluginFunctions->getvalue && RUNNING == mRunning) {
     633           0 :     PluginDestructionGuard guard(this);
     634             : 
     635           0 :     NPError pluginError = NPERR_GENERIC_ERROR;
     636           0 :     NS_TRY_SAFE_CALL_RETURN(pluginError, (*pluginFunctions->getvalue)(&mNPP, variable, value), this,
     637             :                             NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO);
     638           0 :     NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
     639             :     ("NPP GetValue called: this=%p, npp=%p, var=%d, value=%p, return=%d\n",
     640             :     this, &mNPP, variable, value, pluginError));
     641             : 
     642           0 :     if (pluginError == NPERR_NO_ERROR) {
     643           0 :       rv = NS_OK;
     644             :     }
     645             :   }
     646             : 
     647           0 :   return rv;
     648             : }
     649             : 
     650           0 : nsNPAPIPlugin* nsNPAPIPluginInstance::GetPlugin()
     651             : {
     652           0 :   return mPlugin;
     653             : }
     654             : 
     655           0 : nsresult nsNPAPIPluginInstance::GetNPP(NPP* aNPP)
     656             : {
     657           0 :   if (aNPP)
     658           0 :     *aNPP = &mNPP;
     659             :   else
     660           0 :     return NS_ERROR_NULL_POINTER;
     661             : 
     662           0 :   return NS_OK;
     663             : }
     664             : 
     665           0 : NPError nsNPAPIPluginInstance::SetWindowless(bool aWindowless)
     666             : {
     667           0 :   mWindowless = aWindowless;
     668           0 :   return NPERR_NO_ERROR;
     669             : }
     670             : 
     671           0 : NPError nsNPAPIPluginInstance::SetTransparent(bool aTransparent)
     672             : {
     673           0 :   mTransparent = aTransparent;
     674           0 :   return NPERR_NO_ERROR;
     675             : }
     676             : 
     677           0 : NPError nsNPAPIPluginInstance::SetUsesDOMForCursor(bool aUsesDOMForCursor)
     678             : {
     679           0 :   mUsesDOMForCursor = aUsesDOMForCursor;
     680           0 :   return NPERR_NO_ERROR;
     681             : }
     682             : 
     683             : bool
     684           0 : nsNPAPIPluginInstance::UsesDOMForCursor()
     685             : {
     686           0 :   return mUsesDOMForCursor;
     687             : }
     688             : 
     689           0 : void nsNPAPIPluginInstance::SetDrawingModel(NPDrawingModel aModel)
     690             : {
     691           0 :   mDrawingModel = aModel;
     692           0 : }
     693             : 
     694           0 : void nsNPAPIPluginInstance::RedrawPlugin()
     695             : {
     696           0 :   mOwner->RedrawPlugin();
     697           0 : }
     698             : 
     699             : #if defined(XP_MACOSX)
     700             : void nsNPAPIPluginInstance::SetEventModel(NPEventModel aModel)
     701             : {
     702             :   // the event model needs to be set for the object frame immediately
     703             :   if (!mOwner) {
     704             :     NS_WARNING("Trying to set event model without a plugin instance owner!");
     705             :     return;
     706             :   }
     707             : 
     708             :   mOwner->SetEventModel(aModel);
     709             : }
     710             : #endif
     711             : 
     712             : #if defined(MOZ_WIDGET_ANDROID)
     713             : 
     714             : static void SendLifecycleEvent(nsNPAPIPluginInstance* aInstance, uint32_t aAction)
     715             : {
     716             :   ANPEvent event;
     717             :   event.inSize = sizeof(ANPEvent);
     718             :   event.eventType = kLifecycle_ANPEventType;
     719             :   event.data.lifecycle.action = aAction;
     720             :   aInstance->HandleEvent(&event, nullptr);
     721             : }
     722             : 
     723             : void nsNPAPIPluginInstance::NotifyForeground(bool aForeground)
     724             : {
     725             :   PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance::SetForeground this=%p\n foreground=%d",this, aForeground));
     726             :   if (RUNNING != mRunning)
     727             :     return;
     728             : 
     729             :   SendLifecycleEvent(this, aForeground ? kResume_ANPLifecycleAction : kPause_ANPLifecycleAction);
     730             : }
     731             : 
     732             : void nsNPAPIPluginInstance::NotifyOnScreen(bool aOnScreen)
     733             : {
     734             :   PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance::SetOnScreen this=%p\n onScreen=%d",this, aOnScreen));
     735             :   if (RUNNING != mRunning || mOnScreen == aOnScreen)
     736             :     return;
     737             : 
     738             :   mOnScreen = aOnScreen;
     739             :   SendLifecycleEvent(this, aOnScreen ? kOnScreen_ANPLifecycleAction : kOffScreen_ANPLifecycleAction);
     740             : }
     741             : 
     742             : void nsNPAPIPluginInstance::MemoryPressure()
     743             : {
     744             :   PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance::MemoryPressure this=%p\n",this));
     745             :   if (RUNNING != mRunning)
     746             :     return;
     747             : 
     748             :   SendLifecycleEvent(this, kFreeMemory_ANPLifecycleAction);
     749             : }
     750             : 
     751             : void nsNPAPIPluginInstance::NotifyFullScreen(bool aFullScreen)
     752             : {
     753             :   PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance::NotifyFullScreen this=%p\n",this));
     754             : 
     755             :   if (RUNNING != mRunning || mFullScreen == aFullScreen)
     756             :     return;
     757             : 
     758             :   mFullScreen = aFullScreen;
     759             :   SendLifecycleEvent(this, mFullScreen ? kEnterFullScreen_ANPLifecycleAction : kExitFullScreen_ANPLifecycleAction);
     760             : 
     761             :   if (mFullScreen && mFullScreenOrientation != dom::eScreenOrientation_None) {
     762             :     java::GeckoAppShell::LockScreenOrientation(mFullScreenOrientation);
     763             :   }
     764             : }
     765             : 
     766             : void nsNPAPIPluginInstance::NotifySize(nsIntSize size)
     767             : {
     768             :   if (kOpenGL_ANPDrawingModel != GetANPDrawingModel() ||
     769             :       size == mCurrentSize)
     770             :     return;
     771             : 
     772             :   mCurrentSize = size;
     773             : 
     774             :   ANPEvent event;
     775             :   event.inSize = sizeof(ANPEvent);
     776             :   event.eventType = kDraw_ANPEventType;
     777             :   event.data.draw.model = kOpenGL_ANPDrawingModel;
     778             :   event.data.draw.data.surfaceSize.width = size.width;
     779             :   event.data.draw.data.surfaceSize.height = size.height;
     780             : 
     781             :   HandleEvent(&event, nullptr);
     782             : }
     783             : 
     784             : void nsNPAPIPluginInstance::SetANPDrawingModel(uint32_t aModel)
     785             : {
     786             :   mANPDrawingModel = aModel;
     787             : }
     788             : 
     789             : void* nsNPAPIPluginInstance::GetJavaSurface()
     790             : {
     791             :   void* surface = nullptr;
     792             :   nsresult rv = GetValueFromPlugin(kJavaSurface_ANPGetValue, &surface);
     793             :   if (NS_FAILED(rv))
     794             :     return nullptr;
     795             : 
     796             :   return surface;
     797             : }
     798             : 
     799             : void nsNPAPIPluginInstance::PostEvent(void* event)
     800             : {
     801             :   PluginEventRunnable *r = new PluginEventRunnable(this, (ANPEvent*)event);
     802             :   mPostedEvents.AppendElement(RefPtr<PluginEventRunnable>(r));
     803             : 
     804             :   NS_DispatchToMainThread(r);
     805             : }
     806             : 
     807             : void nsNPAPIPluginInstance::SetFullScreenOrientation(uint32_t orientation)
     808             : {
     809             :   if (mFullScreenOrientation == orientation)
     810             :     return;
     811             : 
     812             :   uint32_t oldOrientation = mFullScreenOrientation;
     813             :   mFullScreenOrientation = orientation;
     814             : 
     815             :   if (mFullScreen) {
     816             :     // We're already fullscreen so immediately apply the orientation change
     817             : 
     818             :     if (mFullScreenOrientation != dom::eScreenOrientation_None) {
     819             :       java::GeckoAppShell::LockScreenOrientation(mFullScreenOrientation);
     820             :     } else if (oldOrientation != dom::eScreenOrientation_None) {
     821             :       // We applied an orientation when we entered fullscreen, but
     822             :       // we don't want it anymore
     823             :       java::GeckoAppShell::UnlockScreenOrientation();
     824             :     }
     825             :   }
     826             : }
     827             : 
     828             : void nsNPAPIPluginInstance::PopPostedEvent(PluginEventRunnable* r)
     829             : {
     830             :   mPostedEvents.RemoveElement(r);
     831             : }
     832             : 
     833             : void nsNPAPIPluginInstance::SetWakeLock(bool aLocked)
     834             : {
     835             :   if (aLocked == mWakeLocked)
     836             :     return;
     837             : 
     838             :   mWakeLocked = aLocked;
     839             :   hal::ModifyWakeLock(NS_LITERAL_STRING("screen"),
     840             :                       mWakeLocked ? hal::WAKE_LOCK_ADD_ONE : hal::WAKE_LOCK_REMOVE_ONE,
     841             :                       hal::WAKE_LOCK_NO_CHANGE);
     842             : }
     843             : 
     844             : GLContext* nsNPAPIPluginInstance::GLContext()
     845             : {
     846             :   if (!EnsureGLContext())
     847             :     return nullptr;
     848             : 
     849             :   return sPluginContext;
     850             : }
     851             : 
     852             : class PluginTextureListener
     853             :   : public java::SurfaceTextureListener::Natives<PluginTextureListener>
     854             : {
     855             :   using Base = java::SurfaceTextureListener::Natives<PluginTextureListener>;
     856             : 
     857             :   const nsCOMPtr<nsIRunnable> mCallback;
     858             : public:
     859             :   using Base::AttachNative;
     860             :   using Base::DisposeNative;
     861             : 
     862             :   PluginTextureListener(nsIRunnable* aCallback) : mCallback(aCallback) {}
     863             : 
     864             :   void OnFrameAvailable()
     865             :   {
     866             :     if (NS_IsMainThread()) {
     867             :       mCallback->Run();
     868             :       return;
     869             :     }
     870             :     NS_DispatchToMainThread(mCallback);
     871             :   }
     872             : };
     873             : 
     874             : java::GeckoSurface::LocalRef nsNPAPIPluginInstance::CreateSurface()
     875             : {
     876             :   java::GeckoSurface::LocalRef surf = java::SurfaceAllocator::AcquireSurface(0, 0, false);
     877             :   if (!surf) {
     878             :     return nullptr;
     879             :   }
     880             : 
     881             :   nsCOMPtr<nsIRunnable> frameCallback = NewRunnableMethod("nsNPAPIPluginInstance::OnSurfaceTextureFrameAvailable",
     882             :                                                           this, &nsNPAPIPluginInstance::OnSurfaceTextureFrameAvailable);
     883             : 
     884             :   java::SurfaceTextureListener::LocalRef listener = java::SurfaceTextureListener::New();
     885             : 
     886             :   PluginTextureListener::AttachNative(listener, MakeUnique<PluginTextureListener>(frameCallback.get()));
     887             : 
     888             :   java::GeckoSurfaceTexture::LocalRef gst = java::GeckoSurfaceTexture::Lookup(surf->GetHandle());
     889             :   if (!gst) {
     890             :     return nullptr;
     891             :   }
     892             : 
     893             :   const auto& st = java::sdk::SurfaceTexture::Ref::From(gst);
     894             :   st->SetOnFrameAvailableListener(listener);
     895             : 
     896             :   return surf;
     897             : }
     898             : 
     899             : void nsNPAPIPluginInstance::OnSurfaceTextureFrameAvailable()
     900             : {
     901             :   if (mRunning == RUNNING && mOwner)
     902             :     mOwner->Recomposite();
     903             : }
     904             : 
     905             : void* nsNPAPIPluginInstance::AcquireContentWindow()
     906             : {
     907             :   if (!mContentWindow.NativeWindow()) {
     908             :     mContentSurface = CreateSurface();
     909             :     if (!mContentSurface)
     910             :       return nullptr;
     911             : 
     912             :     mContentWindow = AndroidNativeWindow(mContentSurface);
     913             :   }
     914             : 
     915             :   return mContentWindow.NativeWindow();
     916             : }
     917             : 
     918             : java::GeckoSurface::Param
     919             : nsNPAPIPluginInstance::AsSurface()
     920             : {
     921             :   return mContentSurface;
     922             : }
     923             : 
     924             : void* nsNPAPIPluginInstance::AcquireVideoWindow()
     925             : {
     926             :   java::GeckoSurface::LocalRef surface = CreateSurface();
     927             :   VideoInfo* info = new VideoInfo(surface);
     928             : 
     929             :   void* window = info->mNativeWindow.NativeWindow();
     930             :   mVideos.insert(std::pair<void*, VideoInfo*>(window, info));
     931             : 
     932             :   return window;
     933             : }
     934             : 
     935             : void nsNPAPIPluginInstance::ReleaseVideoWindow(void* window)
     936             : {
     937             :   std::map<void*, VideoInfo*>::iterator it = mVideos.find(window);
     938             :   if (it == mVideos.end())
     939             :     return;
     940             : 
     941             :   delete it->second;
     942             :   mVideos.erase(window);
     943             : }
     944             : 
     945             : void nsNPAPIPluginInstance::SetVideoDimensions(void* window, gfxRect aDimensions)
     946             : {
     947             :   std::map<void*, VideoInfo*>::iterator it;
     948             : 
     949             :   it = mVideos.find(window);
     950             :   if (it == mVideos.end())
     951             :     return;
     952             : 
     953             :   it->second->mDimensions = aDimensions;
     954             : }
     955             : 
     956             : void nsNPAPIPluginInstance::GetVideos(nsTArray<VideoInfo*>& aVideos)
     957             : {
     958             :   std::map<void*, VideoInfo*>::iterator it;
     959             :   for (it = mVideos.begin(); it != mVideos.end(); it++)
     960             :     aVideos.AppendElement(it->second);
     961             : }
     962             : 
     963             : nsNPAPIPluginInstance* nsNPAPIPluginInstance::GetFromNPP(NPP npp)
     964             : {
     965             :   std::map<NPP, nsNPAPIPluginInstance*>::iterator it;
     966             : 
     967             :   it = sPluginNPPMap.find(npp);
     968             :   if (it == sPluginNPPMap.end())
     969             :     return nullptr;
     970             : 
     971             :   return it->second;
     972             : }
     973             : 
     974             : #endif
     975             : 
     976           0 : nsresult nsNPAPIPluginInstance::GetDrawingModel(int32_t* aModel)
     977             : {
     978           0 :   *aModel = (int32_t)mDrawingModel;
     979           0 :   return NS_OK;
     980             : }
     981             : 
     982           0 : nsresult nsNPAPIPluginInstance::IsRemoteDrawingCoreAnimation(bool* aDrawing)
     983             : {
     984             : #ifdef XP_MACOSX
     985             :   if (!mPlugin)
     986             :       return NS_ERROR_FAILURE;
     987             : 
     988             :   PluginLibrary* library = mPlugin->GetLibrary();
     989             :   if (!library)
     990             :       return NS_ERROR_FAILURE;
     991             : 
     992             :   return library->IsRemoteDrawingCoreAnimation(&mNPP, aDrawing);
     993             : #else
     994           0 :   return NS_ERROR_FAILURE;
     995             : #endif
     996             : }
     997             : 
     998             : nsresult
     999           0 : nsNPAPIPluginInstance::ContentsScaleFactorChanged(double aContentsScaleFactor)
    1000             : {
    1001             : #if defined(XP_MACOSX) || defined(XP_WIN)
    1002             :   if (!mPlugin)
    1003             :       return NS_ERROR_FAILURE;
    1004             : 
    1005             :   PluginLibrary* library = mPlugin->GetLibrary();
    1006             :   if (!library)
    1007             :       return NS_ERROR_FAILURE;
    1008             : 
    1009             :   // We only need to call this if the plugin is running OOP.
    1010             :   if (!library->IsOOP())
    1011             :       return NS_OK;
    1012             : 
    1013             :   return library->ContentsScaleFactorChanged(&mNPP, aContentsScaleFactor);
    1014             : #else
    1015           0 :   return NS_ERROR_FAILURE;
    1016             : #endif
    1017             : }
    1018             : 
    1019             : nsresult
    1020           0 : nsNPAPIPluginInstance::CSSZoomFactorChanged(float aCSSZoomFactor)
    1021             : {
    1022           0 :   if (RUNNING != mRunning)
    1023           0 :     return NS_OK;
    1024             : 
    1025           0 :   PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance informing plugin of CSS Zoom Factor change this=%p\n",this));
    1026             : 
    1027           0 :   if (!mPlugin || !mPlugin->GetLibrary())
    1028           0 :     return NS_ERROR_FAILURE;
    1029             : 
    1030           0 :   NPPluginFuncs* pluginFunctions = mPlugin->PluginFuncs();
    1031             : 
    1032           0 :   if (!pluginFunctions->setvalue)
    1033           0 :     return NS_ERROR_FAILURE;
    1034             : 
    1035           0 :   PluginDestructionGuard guard(this);
    1036             : 
    1037             :   NPError error;
    1038           0 :   double value = static_cast<double>(aCSSZoomFactor);
    1039           0 :   NS_TRY_SAFE_CALL_RETURN(error, (*pluginFunctions->setvalue)(&mNPP, NPNVCSSZoomFactor, &value), this,
    1040             :                           NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO);
    1041           0 :   return (error == NPERR_NO_ERROR) ? NS_OK : NS_ERROR_FAILURE;
    1042             : }
    1043             : 
    1044             : nsresult
    1045           0 : nsNPAPIPluginInstance::GetJSObject(JSContext *cx, JSObject** outObject)
    1046             : {
    1047           0 :   if (mHaveJavaC2PJSObjectQuirk) {
    1048           0 :     return NS_ERROR_FAILURE;
    1049             :   }
    1050             : 
    1051           0 :   NPObject *npobj = nullptr;
    1052           0 :   nsresult rv = GetValueFromPlugin(NPPVpluginScriptableNPObject, &npobj);
    1053           0 :   if (NS_FAILED(rv) || !npobj)
    1054           0 :     return NS_ERROR_FAILURE;
    1055             : 
    1056           0 :   *outObject = nsNPObjWrapper::GetNewOrUsed(&mNPP, cx, npobj);
    1057             : 
    1058           0 :   _releaseobject(npobj);
    1059             : 
    1060           0 :   return NS_OK;
    1061             : }
    1062             : 
    1063             : void
    1064           0 : nsNPAPIPluginInstance::SetCached(bool aCache)
    1065             : {
    1066           0 :   mCached = aCache;
    1067           0 : }
    1068             : 
    1069             : bool
    1070           0 : nsNPAPIPluginInstance::ShouldCache()
    1071             : {
    1072           0 :   return mCached;
    1073             : }
    1074             : 
    1075             : nsresult
    1076           0 : nsNPAPIPluginInstance::IsWindowless(bool* isWindowless)
    1077             : {
    1078             : #if defined(MOZ_WIDGET_ANDROID) || defined(XP_MACOSX)
    1079             :   // All OS X plugins are windowless.
    1080             :   // On android, pre-honeycomb, all plugins are treated as windowless.
    1081             :   *isWindowless = true;
    1082             : #else
    1083           0 :   *isWindowless = mWindowless;
    1084             : #endif
    1085           0 :   return NS_OK;
    1086             : }
    1087             : 
    1088           0 : class MOZ_STACK_CLASS AutoPluginLibraryCall
    1089             : {
    1090             : public:
    1091           0 :   explicit AutoPluginLibraryCall(nsNPAPIPluginInstance* aThis)
    1092           0 :     : mThis(aThis), mGuard(aThis), mLibrary(nullptr)
    1093             :   {
    1094           0 :     nsNPAPIPlugin* plugin = mThis->GetPlugin();
    1095           0 :     if (plugin)
    1096           0 :       mLibrary = plugin->GetLibrary();
    1097           0 :   }
    1098           0 :   explicit operator bool() { return !!mLibrary; }
    1099           0 :   PluginLibrary* operator->() { return mLibrary; }
    1100             : 
    1101             : private:
    1102             :   nsNPAPIPluginInstance* mThis;
    1103             :   PluginDestructionGuard mGuard;
    1104             :   PluginLibrary* mLibrary;
    1105             : };
    1106             : 
    1107             : nsresult
    1108           0 : nsNPAPIPluginInstance::AsyncSetWindow(NPWindow* window)
    1109             : {
    1110           0 :   if (RUNNING != mRunning)
    1111           0 :     return NS_OK;
    1112             : 
    1113           0 :   AutoPluginLibraryCall library(this);
    1114           0 :   if (!library)
    1115           0 :     return NS_ERROR_FAILURE;
    1116             : 
    1117           0 :   return library->AsyncSetWindow(&mNPP, window);
    1118             : }
    1119             : 
    1120             : nsresult
    1121           0 : nsNPAPIPluginInstance::GetImageContainer(ImageContainer**aContainer)
    1122             : {
    1123           0 :   *aContainer = nullptr;
    1124             : 
    1125           0 :   if (RUNNING != mRunning)
    1126           0 :     return NS_OK;
    1127             : 
    1128           0 :   AutoPluginLibraryCall library(this);
    1129           0 :   return !library ? NS_ERROR_FAILURE : library->GetImageContainer(&mNPP, aContainer);
    1130             : }
    1131             : 
    1132             : nsresult
    1133           0 : nsNPAPIPluginInstance::GetImageSize(nsIntSize* aSize)
    1134             : {
    1135           0 :   *aSize = nsIntSize(0, 0);
    1136             : 
    1137           0 :   if (RUNNING != mRunning)
    1138           0 :     return NS_OK;
    1139             : 
    1140           0 :   AutoPluginLibraryCall library(this);
    1141           0 :   return !library ? NS_ERROR_FAILURE : library->GetImageSize(&mNPP, aSize);
    1142             : }
    1143             : 
    1144             : #if defined(XP_WIN)
    1145             : nsresult
    1146             : nsNPAPIPluginInstance::GetScrollCaptureContainer(ImageContainer**aContainer)
    1147             : {
    1148             :   *aContainer = nullptr;
    1149             : 
    1150             :   if (RUNNING != mRunning)
    1151             :     return NS_OK;
    1152             : 
    1153             :   AutoPluginLibraryCall library(this);
    1154             :   return !library ? NS_ERROR_FAILURE : library->GetScrollCaptureContainer(&mNPP, aContainer);
    1155             : }
    1156             : #endif
    1157             : 
    1158             : nsresult
    1159           0 : nsNPAPIPluginInstance::HandledWindowedPluginKeyEvent(
    1160             :                          const NativeEventData& aKeyEventData,
    1161             :                          bool aIsConsumed)
    1162             : {
    1163           0 :   if (NS_WARN_IF(!mPlugin)) {
    1164           0 :     return NS_ERROR_FAILURE;
    1165             :   }
    1166             : 
    1167           0 :   PluginLibrary* library = mPlugin->GetLibrary();
    1168           0 :   if (NS_WARN_IF(!library)) {
    1169           0 :     return NS_ERROR_FAILURE;
    1170             :   }
    1171           0 :   return library->HandledWindowedPluginKeyEvent(&mNPP, aKeyEventData,
    1172           0 :                                                 aIsConsumed);
    1173             : }
    1174             : 
    1175             : void
    1176           0 : nsNPAPIPluginInstance::DidComposite()
    1177             : {
    1178           0 :   if (RUNNING != mRunning)
    1179           0 :     return;
    1180             : 
    1181           0 :   AutoPluginLibraryCall library(this);
    1182           0 :   library->DidComposite(&mNPP);
    1183             : }
    1184             : 
    1185             : nsresult
    1186           0 : nsNPAPIPluginInstance::NotifyPainted(void)
    1187             : {
    1188           0 :   NS_NOTREACHED("Dead code, shouldn't be called.");
    1189           0 :   return NS_ERROR_NOT_IMPLEMENTED;
    1190             : }
    1191             : 
    1192             : nsresult
    1193           0 : nsNPAPIPluginInstance::GetIsOOP(bool* aIsAsync)
    1194             : {
    1195           0 :   AutoPluginLibraryCall library(this);
    1196           0 :   if (!library)
    1197           0 :     return NS_ERROR_FAILURE;
    1198             : 
    1199           0 :   *aIsAsync = library->IsOOP();
    1200           0 :   return NS_OK;
    1201             : }
    1202             : 
    1203             : nsresult
    1204           0 : nsNPAPIPluginInstance::SetBackgroundUnknown()
    1205             : {
    1206           0 :   if (RUNNING != mRunning)
    1207           0 :     return NS_OK;
    1208             : 
    1209           0 :   AutoPluginLibraryCall library(this);
    1210           0 :   if (!library)
    1211           0 :     return NS_ERROR_FAILURE;
    1212             : 
    1213           0 :   return library->SetBackgroundUnknown(&mNPP);
    1214             : }
    1215             : 
    1216             : nsresult
    1217           0 : nsNPAPIPluginInstance::BeginUpdateBackground(nsIntRect* aRect,
    1218             :                                              DrawTarget** aDrawTarget)
    1219             : {
    1220           0 :   if (RUNNING != mRunning)
    1221           0 :     return NS_OK;
    1222             : 
    1223           0 :   AutoPluginLibraryCall library(this);
    1224           0 :   if (!library)
    1225           0 :     return NS_ERROR_FAILURE;
    1226             : 
    1227           0 :   return library->BeginUpdateBackground(&mNPP, *aRect, aDrawTarget);
    1228             : }
    1229             : 
    1230             : nsresult
    1231           0 : nsNPAPIPluginInstance::EndUpdateBackground(nsIntRect* aRect)
    1232             : {
    1233           0 :   if (RUNNING != mRunning)
    1234           0 :     return NS_OK;
    1235             : 
    1236           0 :   AutoPluginLibraryCall library(this);
    1237           0 :   if (!library)
    1238           0 :     return NS_ERROR_FAILURE;
    1239             : 
    1240           0 :   return library->EndUpdateBackground(&mNPP, *aRect);
    1241             : }
    1242             : 
    1243             : nsresult
    1244           0 : nsNPAPIPluginInstance::IsTransparent(bool* isTransparent)
    1245             : {
    1246           0 :   *isTransparent = mTransparent;
    1247           0 :   return NS_OK;
    1248             : }
    1249             : 
    1250             : nsresult
    1251           0 : nsNPAPIPluginInstance::GetFormValue(nsAString& aValue)
    1252             : {
    1253           0 :   aValue.Truncate();
    1254             : 
    1255           0 :   char *value = nullptr;
    1256           0 :   nsresult rv = GetValueFromPlugin(NPPVformValue, &value);
    1257           0 :   if (NS_FAILED(rv) || !value)
    1258           0 :     return NS_ERROR_FAILURE;
    1259             : 
    1260           0 :   CopyUTF8toUTF16(value, aValue);
    1261             : 
    1262             :   // NPPVformValue allocates with NPN_MemAlloc(), which uses
    1263             :   // nsMemory.
    1264           0 :   free(value);
    1265             : 
    1266           0 :   return NS_OK;
    1267             : }
    1268             : 
    1269             : nsresult
    1270           0 : nsNPAPIPluginInstance::PushPopupsEnabledState(bool aEnabled)
    1271             : {
    1272           0 :   nsCOMPtr<nsPIDOMWindowOuter> window = GetDOMWindow();
    1273           0 :   if (!window)
    1274           0 :     return NS_ERROR_FAILURE;
    1275             : 
    1276             :   PopupControlState oldState =
    1277           0 :     window->PushPopupControlState(aEnabled ? openAllowed : openAbused,
    1278           0 :                                   true);
    1279             : 
    1280           0 :   if (!mPopupStates.AppendElement(oldState)) {
    1281             :     // Appending to our state stack failed, pop what we just pushed.
    1282           0 :     window->PopPopupControlState(oldState);
    1283           0 :     return NS_ERROR_FAILURE;
    1284             :   }
    1285             : 
    1286           0 :   return NS_OK;
    1287             : }
    1288             : 
    1289             : nsresult
    1290           0 : nsNPAPIPluginInstance::PopPopupsEnabledState()
    1291             : {
    1292           0 :   int32_t last = mPopupStates.Length() - 1;
    1293             : 
    1294           0 :   if (last < 0) {
    1295             :     // Nothing to pop.
    1296           0 :     return NS_OK;
    1297             :   }
    1298             : 
    1299           0 :   nsCOMPtr<nsPIDOMWindowOuter> window = GetDOMWindow();
    1300           0 :   if (!window)
    1301           0 :     return NS_ERROR_FAILURE;
    1302             : 
    1303           0 :   PopupControlState &oldState = mPopupStates[last];
    1304             : 
    1305           0 :   window->PopPopupControlState(oldState);
    1306             : 
    1307           0 :   mPopupStates.RemoveElementAt(last);
    1308             : 
    1309           0 :   return NS_OK;
    1310             : }
    1311             : 
    1312             : nsresult
    1313           0 : nsNPAPIPluginInstance::GetPluginAPIVersion(uint16_t* version)
    1314             : {
    1315           0 :   NS_ENSURE_ARG_POINTER(version);
    1316             : 
    1317           0 :   if (!mPlugin)
    1318           0 :     return NS_ERROR_FAILURE;
    1319             : 
    1320           0 :   if (!mPlugin->GetLibrary())
    1321           0 :     return NS_ERROR_FAILURE;
    1322             : 
    1323           0 :   NPPluginFuncs* pluginFunctions = mPlugin->PluginFuncs();
    1324             : 
    1325           0 :   *version = pluginFunctions->version;
    1326             : 
    1327           0 :   return NS_OK;
    1328             : }
    1329             : 
    1330             : nsresult
    1331           0 : nsNPAPIPluginInstance::PrivateModeStateChanged(bool enabled)
    1332             : {
    1333           0 :   if (RUNNING != mRunning)
    1334           0 :     return NS_OK;
    1335             : 
    1336           0 :   PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance informing plugin of private mode state change this=%p\n",this));
    1337             : 
    1338           0 :   if (!mPlugin || !mPlugin->GetLibrary())
    1339           0 :     return NS_ERROR_FAILURE;
    1340             : 
    1341           0 :   NPPluginFuncs* pluginFunctions = mPlugin->PluginFuncs();
    1342             : 
    1343           0 :   if (!pluginFunctions->setvalue)
    1344           0 :     return NS_ERROR_FAILURE;
    1345             : 
    1346           0 :   PluginDestructionGuard guard(this);
    1347             : 
    1348             :   NPError error;
    1349           0 :   NPBool value = static_cast<NPBool>(enabled);
    1350           0 :   NS_TRY_SAFE_CALL_RETURN(error, (*pluginFunctions->setvalue)(&mNPP, NPNVprivateModeBool, &value), this,
    1351             :                           NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO);
    1352           0 :   return (error == NPERR_NO_ERROR) ? NS_OK : NS_ERROR_FAILURE;
    1353             : }
    1354             : 
    1355             : nsresult
    1356           0 : nsNPAPIPluginInstance::IsPrivateBrowsing(bool* aEnabled)
    1357             : {
    1358           0 :   if (!mOwner)
    1359           0 :     return NS_ERROR_FAILURE;
    1360             : 
    1361           0 :   nsCOMPtr<nsIDocument> doc;
    1362           0 :   mOwner->GetDocument(getter_AddRefs(doc));
    1363           0 :   NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
    1364             : 
    1365           0 :   nsCOMPtr<nsPIDOMWindowOuter> domwindow = doc->GetWindow();
    1366           0 :   NS_ENSURE_TRUE(domwindow, NS_ERROR_FAILURE);
    1367             : 
    1368           0 :   nsCOMPtr<nsIDocShell> docShell = domwindow->GetDocShell();
    1369           0 :   nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(docShell);
    1370           0 :   *aEnabled = (loadContext && loadContext->UsePrivateBrowsing());
    1371           0 :   return NS_OK;
    1372             : }
    1373             : 
    1374             : static void
    1375           0 : PluginTimerCallback(nsITimer *aTimer, void *aClosure)
    1376             : {
    1377           0 :   nsNPAPITimer* t = (nsNPAPITimer*)aClosure;
    1378           0 :   NPP npp = t->npp;
    1379           0 :   uint32_t id = t->id;
    1380             : 
    1381           0 :   PLUGIN_LOG(PLUGIN_LOG_NOISY, ("nsNPAPIPluginInstance running plugin timer callback this=%p\n", npp->ndata));
    1382             : 
    1383             :   MAIN_THREAD_JNI_REF_GUARD;
    1384             :   // Some plugins (Flash on Android) calls unscheduletimer
    1385             :   // from this callback.
    1386           0 :   t->inCallback = true;
    1387           0 :   (*(t->callback))(npp, id);
    1388           0 :   t->inCallback = false;
    1389             : 
    1390             :   // Make sure we still have an instance and the timer is still alive
    1391             :   // after the callback.
    1392           0 :   nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance*)npp->ndata;
    1393           0 :   if (!inst || !inst->TimerWithID(id, nullptr))
    1394           0 :     return;
    1395             : 
    1396             :   // use UnscheduleTimer to clean up if this is a one-shot timer
    1397             :   uint32_t timerType;
    1398           0 :   t->timer->GetType(&timerType);
    1399           0 :   if (t->needUnschedule || timerType == nsITimer::TYPE_ONE_SHOT)
    1400           0 :     inst->UnscheduleTimer(id);
    1401             : }
    1402             : 
    1403             : nsNPAPITimer*
    1404           0 : nsNPAPIPluginInstance::TimerWithID(uint32_t id, uint32_t* index)
    1405             : {
    1406           0 :   uint32_t len = mTimers.Length();
    1407           0 :   for (uint32_t i = 0; i < len; i++) {
    1408           0 :     if (mTimers[i]->id == id) {
    1409           0 :       if (index)
    1410           0 :         *index = i;
    1411           0 :       return mTimers[i];
    1412             :     }
    1413             :   }
    1414           0 :   return nullptr;
    1415             : }
    1416             : 
    1417             : uint32_t
    1418           0 : nsNPAPIPluginInstance::ScheduleTimer(uint32_t interval, NPBool repeat, void (*timerFunc)(NPP npp, uint32_t timerID))
    1419             : {
    1420           0 :   if (RUNNING != mRunning)
    1421           0 :     return 0;
    1422             : 
    1423           0 :   nsNPAPITimer *newTimer = new nsNPAPITimer();
    1424             : 
    1425           0 :   newTimer->inCallback = newTimer->needUnschedule = false;
    1426           0 :   newTimer->npp = &mNPP;
    1427             : 
    1428             :   // generate ID that is unique to this instance
    1429           0 :   uint32_t uniqueID = mTimers.Length();
    1430           0 :   while ((uniqueID == 0) || TimerWithID(uniqueID, nullptr))
    1431           0 :     uniqueID++;
    1432           0 :   newTimer->id = uniqueID;
    1433             : 
    1434             :   // create new xpcom timer, scheduled correctly
    1435             :   nsresult rv;
    1436           0 :   nsCOMPtr<nsITimer> xpcomTimer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv);
    1437           0 :   if (NS_FAILED(rv)) {
    1438           0 :     delete newTimer;
    1439           0 :     return 0;
    1440             :   }
    1441           0 :   const short timerType = (repeat ? (short)nsITimer::TYPE_REPEATING_SLACK : (short)nsITimer::TYPE_ONE_SHOT);
    1442           0 :   xpcomTimer->InitWithNamedFuncCallback(PluginTimerCallback,
    1443             :                                         newTimer,
    1444             :                                         interval,
    1445             :                                         timerType,
    1446           0 :                                         "nsNPAPIPluginInstance::ScheduleTimer");
    1447           0 :   newTimer->timer = xpcomTimer;
    1448             : 
    1449             :   // save callback function
    1450           0 :   newTimer->callback = timerFunc;
    1451             : 
    1452             :   // add timer to timers array
    1453           0 :   mTimers.AppendElement(newTimer);
    1454             : 
    1455           0 :   return newTimer->id;
    1456             : }
    1457             : 
    1458             : void
    1459           0 : nsNPAPIPluginInstance::UnscheduleTimer(uint32_t timerID)
    1460             : {
    1461             :   // find the timer struct by ID
    1462             :   uint32_t index;
    1463           0 :   nsNPAPITimer* t = TimerWithID(timerID, &index);
    1464           0 :   if (!t)
    1465           0 :     return;
    1466             : 
    1467           0 :   if (t->inCallback) {
    1468           0 :     t->needUnschedule = true;
    1469           0 :     return;
    1470             :   }
    1471             : 
    1472             :   // cancel the timer
    1473           0 :   t->timer->Cancel();
    1474             : 
    1475             :   // remove timer struct from array
    1476           0 :   mTimers.RemoveElementAt(index);
    1477             : 
    1478             :   // delete timer
    1479           0 :   delete t;
    1480             : }
    1481             : 
    1482             : NPBool
    1483           0 : nsNPAPIPluginInstance::ConvertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace,
    1484             :                                     double *destX, double *destY, NPCoordinateSpace destSpace)
    1485             : {
    1486           0 :   if (mOwner) {
    1487           0 :     return mOwner->ConvertPoint(sourceX, sourceY, sourceSpace, destX, destY, destSpace);
    1488             :   }
    1489             : 
    1490           0 :   return false;
    1491             : }
    1492             : 
    1493             : nsresult
    1494           0 : nsNPAPIPluginInstance::GetDOMElement(nsIDOMElement* *result)
    1495             : {
    1496           0 :   if (!mOwner) {
    1497           0 :     *result = nullptr;
    1498           0 :     return NS_ERROR_FAILURE;
    1499             :   }
    1500             : 
    1501           0 :   return mOwner->GetDOMElement(result);
    1502             : }
    1503             : 
    1504             : nsresult
    1505           0 : nsNPAPIPluginInstance::InvalidateRect(NPRect *invalidRect)
    1506             : {
    1507           0 :   if (RUNNING != mRunning)
    1508           0 :     return NS_OK;
    1509             : 
    1510           0 :   if (!mOwner)
    1511           0 :     return NS_ERROR_FAILURE;
    1512             : 
    1513           0 :   return mOwner->InvalidateRect(invalidRect);
    1514             : }
    1515             : 
    1516             : nsresult
    1517           0 : nsNPAPIPluginInstance::InvalidateRegion(NPRegion invalidRegion)
    1518             : {
    1519           0 :   if (RUNNING != mRunning)
    1520           0 :     return NS_OK;
    1521             : 
    1522           0 :   if (!mOwner)
    1523           0 :     return NS_ERROR_FAILURE;
    1524             : 
    1525           0 :   return mOwner->InvalidateRegion(invalidRegion);
    1526             : }
    1527             : 
    1528             : nsresult
    1529           0 : nsNPAPIPluginInstance::GetMIMEType(const char* *result)
    1530             : {
    1531           0 :   if (!mMIMEType)
    1532           0 :     *result = "";
    1533             :   else
    1534           0 :     *result = mMIMEType;
    1535             : 
    1536           0 :   return NS_OK;
    1537             : }
    1538             : 
    1539             : nsPluginInstanceOwner*
    1540           0 : nsNPAPIPluginInstance::GetOwner()
    1541             : {
    1542           0 :   return mOwner;
    1543             : }
    1544             : 
    1545             : void
    1546           0 : nsNPAPIPluginInstance::SetOwner(nsPluginInstanceOwner *aOwner)
    1547             : {
    1548           0 :   mOwner = aOwner;
    1549           0 : }
    1550             : 
    1551             : nsresult
    1552           0 : nsNPAPIPluginInstance::AsyncSetWindow(NPWindow& window)
    1553             : {
    1554           0 :   return NS_ERROR_NOT_IMPLEMENTED;
    1555             : }
    1556             : 
    1557             : void
    1558           0 : nsNPAPIPluginInstance::URLRedirectResponse(void* notifyData, NPBool allow)
    1559             : {
    1560           0 :   if (!notifyData) {
    1561           0 :     return;
    1562             :   }
    1563             : 
    1564           0 :   uint32_t listenerCount = mStreamListeners.Length();
    1565           0 :   for (uint32_t i = 0; i < listenerCount; i++) {
    1566           0 :     nsNPAPIPluginStreamListener* currentListener = mStreamListeners[i];
    1567           0 :     if (currentListener->GetNotifyData() == notifyData) {
    1568           0 :       currentListener->URLRedirectResponse(allow);
    1569             :     }
    1570             :   }
    1571             : }
    1572             : 
    1573             : NPError
    1574           0 : nsNPAPIPluginInstance::InitAsyncSurface(NPSize *size, NPImageFormat format,
    1575             :                                         void *initData, NPAsyncSurface *surface)
    1576             : {
    1577           0 :   if (mOwner) {
    1578           0 :     return mOwner->InitAsyncSurface(size, format, initData, surface);
    1579             :   }
    1580             : 
    1581           0 :   return NPERR_GENERIC_ERROR;
    1582             : }
    1583             : 
    1584             : NPError
    1585           0 : nsNPAPIPluginInstance::FinalizeAsyncSurface(NPAsyncSurface *surface)
    1586             : {
    1587           0 :   if (mOwner) {
    1588           0 :     return mOwner->FinalizeAsyncSurface(surface);
    1589             :   }
    1590             : 
    1591           0 :   return NPERR_GENERIC_ERROR;
    1592             : }
    1593             : 
    1594             : void
    1595           0 : nsNPAPIPluginInstance::SetCurrentAsyncSurface(NPAsyncSurface *surface, NPRect *changed)
    1596             : {
    1597           0 :   if (mOwner) {
    1598           0 :     mOwner->SetCurrentAsyncSurface(surface, changed);
    1599             :   }
    1600           0 : }
    1601             : 
    1602             : static bool
    1603           0 : GetJavaVersionFromMimetype(nsPluginTag* pluginTag, nsCString& version)
    1604             : {
    1605           0 :   for (uint32_t i = 0; i < pluginTag->MimeTypes().Length(); ++i) {
    1606           0 :     nsCString type = pluginTag->MimeTypes()[i];
    1607           0 :     nsAutoCString jpi("application/x-java-applet;jpi-version=");
    1608             : 
    1609           0 :     int32_t idx = type.Find(jpi, false, 0, -1);
    1610           0 :     if (idx != 0) {
    1611           0 :       continue;
    1612             :     }
    1613             : 
    1614           0 :     type.Cut(0, jpi.Length());
    1615           0 :     if (type.IsEmpty()) {
    1616           0 :       continue;
    1617             :     }
    1618             : 
    1619           0 :     type.ReplaceChar('_', '.');
    1620           0 :     version = type;
    1621           0 :     return true;
    1622             :   }
    1623             : 
    1624           0 :   return false;
    1625             : }
    1626             : 
    1627             : void
    1628           0 : nsNPAPIPluginInstance::CheckJavaC2PJSObjectQuirk(uint16_t paramCount,
    1629             :                                                  const char* const* paramNames,
    1630             :                                                  const char* const* paramValues)
    1631             : {
    1632           0 :   if (!mMIMEType || !mPlugin) {
    1633           0 :     return;
    1634             :   }
    1635             : 
    1636             :   nsPluginTagType tagtype;
    1637           0 :   nsresult rv = GetTagType(&tagtype);
    1638           0 :   if (NS_FAILED(rv) ||
    1639           0 :       (tagtype != nsPluginTagType_Applet)) {
    1640           0 :     return;
    1641             :   }
    1642             : 
    1643           0 :   RefPtr<nsPluginHost> pluginHost = nsPluginHost::GetInst();
    1644           0 :   if (!pluginHost) {
    1645           0 :     return;
    1646             :   }
    1647             : 
    1648           0 :   nsPluginTag* pluginTag = pluginHost->TagForPlugin(mPlugin);
    1649           0 :   if (!pluginTag ||
    1650           0 :       !pluginTag->mIsJavaPlugin) {
    1651           0 :     return;
    1652             :   }
    1653             : 
    1654             :   // check the params for "code" being present and non-empty
    1655           0 :   bool haveCodeParam = false;
    1656           0 :   bool isCodeParamEmpty = true;
    1657             : 
    1658           0 :   for (uint16_t i = paramCount; i > 0; --i) {
    1659           0 :     if (PL_strcasecmp(paramNames[i - 1], "code") == 0) {
    1660           0 :       haveCodeParam = true;
    1661           0 :       if (strlen(paramValues[i - 1]) > 0) {
    1662           0 :         isCodeParamEmpty = false;
    1663             :       }
    1664           0 :       break;
    1665             :     }
    1666             :   }
    1667             : 
    1668             :   // Due to the Java version being specified inconsistently across platforms
    1669             :   // check the version via the mimetype for choosing specific Java versions
    1670           0 :   nsCString javaVersion;
    1671           0 :   if (!GetJavaVersionFromMimetype(pluginTag, javaVersion)) {
    1672           0 :     return;
    1673             :   }
    1674             : 
    1675           0 :   mozilla::Version version(javaVersion.get());
    1676             : 
    1677           0 :   if (version >= "1.7.0.4") {
    1678           0 :     return;
    1679             :   }
    1680             : 
    1681           0 :   if (!haveCodeParam && version >= "1.6.0.34" && version < "1.7") {
    1682           0 :     return;
    1683             :   }
    1684             : 
    1685           0 :   if (haveCodeParam && !isCodeParamEmpty) {
    1686           0 :     return;
    1687             :   }
    1688             : 
    1689           0 :   mHaveJavaC2PJSObjectQuirk = true;
    1690             : }
    1691             : 
    1692             : double
    1693           0 : nsNPAPIPluginInstance::GetContentsScaleFactor()
    1694             : {
    1695           0 :   double scaleFactor = 1.0;
    1696           0 :   if (mOwner) {
    1697           0 :     mOwner->GetContentsScaleFactor(&scaleFactor);
    1698             :   }
    1699           0 :   return scaleFactor;
    1700             : }
    1701             : 
    1702             : float
    1703           0 : nsNPAPIPluginInstance::GetCSSZoomFactor()
    1704             : {
    1705           0 :   float zoomFactor = 1.0;
    1706           0 :   if (mOwner) {
    1707           0 :     mOwner->GetCSSZoomFactor(&zoomFactor);
    1708             :   }
    1709           0 :   return zoomFactor;
    1710             : }
    1711             : 
    1712             : nsresult
    1713           0 : nsNPAPIPluginInstance::GetRunID(uint32_t* aRunID)
    1714             : {
    1715           0 :   if (NS_WARN_IF(!aRunID)) {
    1716           0 :     return NS_ERROR_INVALID_POINTER;
    1717             :   }
    1718             : 
    1719           0 :   if (NS_WARN_IF(!mPlugin)) {
    1720           0 :     return NS_ERROR_FAILURE;
    1721             :   }
    1722             : 
    1723           0 :   PluginLibrary* library = mPlugin->GetLibrary();
    1724           0 :   if (!library) {
    1725           0 :     return NS_ERROR_FAILURE;
    1726             :   }
    1727             : 
    1728           0 :   return library->GetRunID(aRunID);
    1729             : }
    1730             : 
    1731             : nsresult
    1732           0 : nsNPAPIPluginInstance::CreateAudioChannelAgentIfNeeded()
    1733             : {
    1734           0 :   if (mAudioChannelAgent) {
    1735           0 :     return NS_OK;
    1736             :   }
    1737             : 
    1738             :   nsresult rv;
    1739           0 :   mAudioChannelAgent = do_CreateInstance("@mozilla.org/audiochannelagent;1", &rv);
    1740           0 :   if (NS_WARN_IF(!mAudioChannelAgent)) {
    1741           0 :     return NS_ERROR_FAILURE;
    1742             :   }
    1743             : 
    1744           0 :   nsCOMPtr<nsPIDOMWindowOuter> window = GetDOMWindow();
    1745           0 :   if (NS_WARN_IF(!window)) {
    1746           0 :     return NS_ERROR_FAILURE;
    1747             :   }
    1748             : 
    1749           0 :   rv = mAudioChannelAgent->Init(window->GetCurrentInnerWindow(),
    1750           0 :                                (int32_t)AudioChannelService::GetDefaultAudioChannel(),
    1751           0 :                                this);
    1752           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
    1753           0 :     return rv;
    1754             :   }
    1755           0 :   return NS_OK;
    1756             : }
    1757             : 
    1758             : void
    1759           0 : nsNPAPIPluginInstance::NotifyStartedPlaying()
    1760             : {
    1761           0 :   nsresult rv = CreateAudioChannelAgentIfNeeded();
    1762           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
    1763           0 :     return;
    1764             :   }
    1765             : 
    1766           0 :   MOZ_ASSERT(mAudioChannelAgent);
    1767           0 :   dom::AudioPlaybackConfig config;
    1768           0 :   rv = mAudioChannelAgent->NotifyStartedPlaying(&config,
    1769           0 :                                                 dom::AudioChannelService::AudibleState::eAudible);
    1770           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
    1771           0 :     return;
    1772             :   }
    1773             : 
    1774           0 :   rv = WindowVolumeChanged(config.mVolume, config.mMuted);
    1775           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
    1776           0 :     return;
    1777             :   }
    1778             : 
    1779             :   // Since we only support muting for now, the implementation of suspend
    1780             :   // is equal to muting. Therefore, if we have already muted the plugin,
    1781             :   // then we don't need to call WindowSuspendChanged() again.
    1782           0 :   if (config.mMuted) {
    1783           0 :     return;
    1784             :   }
    1785             : 
    1786           0 :   rv = WindowSuspendChanged(config.mSuspend);
    1787           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
    1788           0 :     return;
    1789             :   }
    1790             : }
    1791             : 
    1792             : void
    1793           0 : nsNPAPIPluginInstance::NotifyStoppedPlaying()
    1794             : {
    1795           0 :   MOZ_ASSERT(mAudioChannelAgent);
    1796             : 
    1797             :   // Reset the attribute.
    1798           0 :   mMuted = false;
    1799           0 :   nsresult rv = mAudioChannelAgent->NotifyStoppedPlaying();
    1800           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
    1801           0 :     return;
    1802             :   }
    1803             : }
    1804             : 
    1805             : NS_IMETHODIMP
    1806           0 : nsNPAPIPluginInstance::WindowVolumeChanged(float aVolume, bool aMuted)
    1807             : {
    1808           0 :   MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
    1809             :          ("nsNPAPIPluginInstance, WindowVolumeChanged, "
    1810             :           "this = %p, aVolume = %f, aMuted = %s\n",
    1811             :           this, aVolume, aMuted ? "true" : "false"));
    1812             : 
    1813             :   // We just support mute/unmute
    1814           0 :   nsresult rv = SetMuted(aMuted);
    1815           0 :   NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "SetMuted failed");
    1816           0 :   if (mMuted != aMuted) {
    1817           0 :     mMuted = aMuted;
    1818           0 :     if (mAudioChannelAgent) {
    1819           0 :       AudioChannelService::AudibleState audible = aMuted ?
    1820             :         AudioChannelService::AudibleState::eNotAudible :
    1821           0 :         AudioChannelService::AudibleState::eAudible;
    1822           0 :       mAudioChannelAgent->NotifyStartedAudible(audible,
    1823           0 :                                                AudioChannelService::AudibleChangedReasons::eVolumeChanged);
    1824             :     }
    1825             :   }
    1826           0 :   return rv;
    1827             : }
    1828             : 
    1829             : NS_IMETHODIMP
    1830           0 : nsNPAPIPluginInstance::WindowSuspendChanged(nsSuspendedTypes aSuspend)
    1831             : {
    1832           0 :   MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
    1833             :          ("nsNPAPIPluginInstance, WindowSuspendChanged, "
    1834             :           "this = %p, aSuspend = %s\n", this, SuspendTypeToStr(aSuspend)));
    1835             : 
    1836             :   // It doesn't support suspended, so we just do something like mute/unmute.
    1837           0 :   WindowVolumeChanged(1.0, /* useless */
    1838           0 :                       aSuspend != nsISuspendedTypes::NONE_SUSPENDED);
    1839           0 :   return NS_OK;
    1840             : }
    1841             : 
    1842             : NS_IMETHODIMP
    1843           0 : nsNPAPIPluginInstance::WindowAudioCaptureChanged(bool aCapture)
    1844             : {
    1845           0 :   return NS_OK;
    1846             : }
    1847             : 
    1848             : nsresult
    1849           0 : nsNPAPIPluginInstance::SetMuted(bool aIsMuted)
    1850             : {
    1851           0 :   if (RUNNING != mRunning)
    1852           0 :     return NS_OK;
    1853             : 
    1854           0 :   PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance informing plugin of mute state change this=%p\n",this));
    1855             : 
    1856           0 :   if (!mPlugin || !mPlugin->GetLibrary())
    1857           0 :     return NS_ERROR_FAILURE;
    1858             : 
    1859           0 :   NPPluginFuncs* pluginFunctions = mPlugin->PluginFuncs();
    1860             : 
    1861           0 :   if (!pluginFunctions->setvalue)
    1862           0 :     return NS_ERROR_FAILURE;
    1863             : 
    1864           0 :   PluginDestructionGuard guard(this);
    1865             : 
    1866             :   NPError error;
    1867           0 :   NPBool value = static_cast<NPBool>(aIsMuted);
    1868           0 :   NS_TRY_SAFE_CALL_RETURN(error, (*pluginFunctions->setvalue)(&mNPP, NPNVmuteAudioBool, &value), this,
    1869             :                           NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO);
    1870           0 :   return (error == NPERR_NO_ERROR) ? NS_OK : NS_ERROR_FAILURE;
    1871             : }

Generated by: LCOV version 1.13