1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1839 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "mozilla/DebugOnly.h" 1.10 + 1.11 +#ifdef MOZ_WIDGET_ANDROID 1.12 +// For ScreenOrientation.h and Hal.h 1.13 +#include "base/basictypes.h" 1.14 +#endif 1.15 + 1.16 +#include "prlog.h" 1.17 +#include "prmem.h" 1.18 +#include "nscore.h" 1.19 +#include "prenv.h" 1.20 + 1.21 +#include "nsNPAPIPluginInstance.h" 1.22 +#include "nsNPAPIPlugin.h" 1.23 +#include "nsNPAPIPluginStreamListener.h" 1.24 +#include "nsPluginHost.h" 1.25 +#include "nsPluginLogging.h" 1.26 +#include "nsContentUtils.h" 1.27 +#include "nsPluginInstanceOwner.h" 1.28 + 1.29 +#include "nsThreadUtils.h" 1.30 +#include "nsIDOMElement.h" 1.31 +#include "nsIDocument.h" 1.32 +#include "nsIDocShell.h" 1.33 +#include "nsIScriptGlobalObject.h" 1.34 +#include "nsIScriptContext.h" 1.35 +#include "nsDirectoryServiceDefs.h" 1.36 +#include "nsJSNPRuntime.h" 1.37 +#include "nsPluginStreamListenerPeer.h" 1.38 +#include "nsSize.h" 1.39 +#include "nsNetCID.h" 1.40 +#include "nsIContent.h" 1.41 +#include "nsVersionComparator.h" 1.42 +#include "mozilla/Preferences.h" 1.43 +#include "mozilla/unused.h" 1.44 +#include "nsILoadContext.h" 1.45 + 1.46 +using namespace mozilla; 1.47 + 1.48 +#ifdef MOZ_WIDGET_ANDROID 1.49 +#include "ANPBase.h" 1.50 +#include <android/log.h> 1.51 +#include "android_npapi.h" 1.52 +#include "mozilla/Mutex.h" 1.53 +#include "mozilla/CondVar.h" 1.54 +#include "AndroidBridge.h" 1.55 +#include "mozilla/dom/ScreenOrientation.h" 1.56 +#include "mozilla/Hal.h" 1.57 +#include "GLContextProvider.h" 1.58 +#include "GLContext.h" 1.59 +#include "TexturePoolOGL.h" 1.60 +#include "GLSharedHandleHelpers.h" 1.61 + 1.62 +using namespace mozilla::gl; 1.63 + 1.64 +typedef nsNPAPIPluginInstance::VideoInfo VideoInfo; 1.65 + 1.66 +class PluginEventRunnable : public nsRunnable 1.67 +{ 1.68 +public: 1.69 + PluginEventRunnable(nsNPAPIPluginInstance* instance, ANPEvent* event) 1.70 + : mInstance(instance), mEvent(*event), mCanceled(false) {} 1.71 + 1.72 + virtual nsresult Run() { 1.73 + if (mCanceled) 1.74 + return NS_OK; 1.75 + 1.76 + mInstance->HandleEvent(&mEvent, nullptr); 1.77 + mInstance->PopPostedEvent(this); 1.78 + return NS_OK; 1.79 + } 1.80 + 1.81 + void Cancel() { mCanceled = true; } 1.82 +private: 1.83 + nsNPAPIPluginInstance* mInstance; 1.84 + ANPEvent mEvent; 1.85 + bool mCanceled; 1.86 +}; 1.87 + 1.88 +static nsRefPtr<GLContext> sPluginContext = nullptr; 1.89 + 1.90 +static bool EnsureGLContext() 1.91 +{ 1.92 + if (!sPluginContext) { 1.93 + gfxIntSize dummySize(16, 16); 1.94 + sPluginContext = GLContextProvider::CreateOffscreen(dummySize, 1.95 + GLContext::SurfaceCaps::Any()); 1.96 + } 1.97 + 1.98 + return sPluginContext != nullptr; 1.99 +} 1.100 + 1.101 +class SharedPluginTexture MOZ_FINAL { 1.102 +public: 1.103 + NS_INLINE_DECL_REFCOUNTING(SharedPluginTexture) 1.104 + 1.105 + SharedPluginTexture() : mLock("SharedPluginTexture.mLock") 1.106 + { 1.107 + } 1.108 + 1.109 + nsNPAPIPluginInstance::TextureInfo Lock() 1.110 + { 1.111 + if (!EnsureGLContext()) { 1.112 + mTextureInfo.mTexture = 0; 1.113 + return mTextureInfo; 1.114 + } 1.115 + 1.116 + if (!mTextureInfo.mTexture && sPluginContext->MakeCurrent()) { 1.117 + sPluginContext->fGenTextures(1, &mTextureInfo.mTexture); 1.118 + } 1.119 + 1.120 + mLock.Lock(); 1.121 + return mTextureInfo; 1.122 + } 1.123 + 1.124 + void Release(nsNPAPIPluginInstance::TextureInfo& aTextureInfo) 1.125 + { 1.126 + mTextureInfo = aTextureInfo; 1.127 + mLock.Unlock(); 1.128 + } 1.129 + 1.130 + SharedTextureHandle CreateSharedHandle() 1.131 + { 1.132 + MutexAutoLock lock(mLock); 1.133 + 1.134 + if (!EnsureGLContext()) 1.135 + return 0; 1.136 + 1.137 + if (mTextureInfo.mWidth == 0 || mTextureInfo.mHeight == 0) 1.138 + return 0; 1.139 + 1.140 + SharedTextureHandle handle = 1.141 + gl::CreateSharedHandle(sPluginContext, 1.142 + gl::SharedTextureShareType::SameProcess, 1.143 + (void*)mTextureInfo.mTexture, 1.144 + gl::SharedTextureBufferType::TextureID); 1.145 + 1.146 + // We want forget about this now, so delete the texture. Assigning it to zero 1.147 + // ensures that we create a new one in Lock() 1.148 + sPluginContext->fDeleteTextures(1, &mTextureInfo.mTexture); 1.149 + mTextureInfo.mTexture = 0; 1.150 + 1.151 + return handle; 1.152 + } 1.153 + 1.154 +private: 1.155 + // Private destructor, to discourage deletion outside of Release(): 1.156 + ~SharedPluginTexture() 1.157 + { 1.158 + } 1.159 + 1.160 + nsNPAPIPluginInstance::TextureInfo mTextureInfo; 1.161 + 1.162 + Mutex mLock; 1.163 +}; 1.164 + 1.165 +static std::map<NPP, nsNPAPIPluginInstance*> sPluginNPPMap; 1.166 + 1.167 +#endif 1.168 + 1.169 +using namespace mozilla; 1.170 +using namespace mozilla::plugins::parent; 1.171 +using namespace mozilla::layers; 1.172 + 1.173 +static NS_DEFINE_IID(kIOutputStreamIID, NS_IOUTPUTSTREAM_IID); 1.174 + 1.175 +NS_IMPL_ISUPPORTS0(nsNPAPIPluginInstance) 1.176 + 1.177 +nsNPAPIPluginInstance::nsNPAPIPluginInstance() 1.178 + : 1.179 + mDrawingModel(kDefaultDrawingModel), 1.180 +#ifdef MOZ_WIDGET_ANDROID 1.181 + mANPDrawingModel(0), 1.182 + mFullScreenOrientation(dom::eScreenOrientation_LandscapePrimary), 1.183 + mWakeLocked(false), 1.184 + mFullScreen(false), 1.185 + mInverted(false), 1.186 +#endif 1.187 + mRunning(NOT_STARTED), 1.188 + mWindowless(false), 1.189 + mTransparent(false), 1.190 + mCached(false), 1.191 + mUsesDOMForCursor(false), 1.192 + mInPluginInitCall(false), 1.193 + mPlugin(nullptr), 1.194 + mMIMEType(nullptr), 1.195 + mOwner(nullptr), 1.196 + mCurrentPluginEvent(nullptr) 1.197 +#ifdef MOZ_WIDGET_ANDROID 1.198 + , mOnScreen(true) 1.199 +#endif 1.200 + , mHaveJavaC2PJSObjectQuirk(false) 1.201 +{ 1.202 + mNPP.pdata = nullptr; 1.203 + mNPP.ndata = this; 1.204 + 1.205 + PLUGIN_LOG(PLUGIN_LOG_BASIC, ("nsNPAPIPluginInstance ctor: this=%p\n",this)); 1.206 + 1.207 +#ifdef MOZ_WIDGET_ANDROID 1.208 + sPluginNPPMap[&mNPP] = this; 1.209 +#endif 1.210 +} 1.211 + 1.212 +nsNPAPIPluginInstance::~nsNPAPIPluginInstance() 1.213 +{ 1.214 + PLUGIN_LOG(PLUGIN_LOG_BASIC, ("nsNPAPIPluginInstance dtor: this=%p\n",this)); 1.215 + 1.216 +#ifdef MOZ_WIDGET_ANDROID 1.217 + sPluginNPPMap.erase(&mNPP); 1.218 +#endif 1.219 + 1.220 + if (mMIMEType) { 1.221 + PR_Free((void *)mMIMEType); 1.222 + mMIMEType = nullptr; 1.223 + } 1.224 +} 1.225 + 1.226 +uint32_t nsNPAPIPluginInstance::gInUnsafePluginCalls = 0; 1.227 + 1.228 +void 1.229 +nsNPAPIPluginInstance::Destroy() 1.230 +{ 1.231 + Stop(); 1.232 + mPlugin = nullptr; 1.233 + 1.234 +#if MOZ_WIDGET_ANDROID 1.235 + if (mContentSurface) 1.236 + mContentSurface->SetFrameAvailableCallback(nullptr); 1.237 + 1.238 + mContentTexture = nullptr; 1.239 + mContentSurface = nullptr; 1.240 + 1.241 + std::map<void*, VideoInfo*>::iterator it; 1.242 + for (it = mVideos.begin(); it != mVideos.end(); it++) { 1.243 + it->second->mSurfaceTexture->SetFrameAvailableCallback(nullptr); 1.244 + delete it->second; 1.245 + } 1.246 + mVideos.clear(); 1.247 + SetWakeLock(false); 1.248 +#endif 1.249 +} 1.250 + 1.251 +TimeStamp 1.252 +nsNPAPIPluginInstance::StopTime() 1.253 +{ 1.254 + return mStopTime; 1.255 +} 1.256 + 1.257 +nsresult nsNPAPIPluginInstance::Initialize(nsNPAPIPlugin *aPlugin, nsPluginInstanceOwner* aOwner, const char* aMIMEType) 1.258 +{ 1.259 + PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance::Initialize this=%p\n",this)); 1.260 + 1.261 + NS_ENSURE_ARG_POINTER(aPlugin); 1.262 + NS_ENSURE_ARG_POINTER(aOwner); 1.263 + 1.264 + mPlugin = aPlugin; 1.265 + mOwner = aOwner; 1.266 + 1.267 + if (aMIMEType) { 1.268 + mMIMEType = (char*)PR_Malloc(strlen(aMIMEType) + 1); 1.269 + if (mMIMEType) { 1.270 + PL_strcpy(mMIMEType, aMIMEType); 1.271 + } 1.272 + } 1.273 + 1.274 + return Start(); 1.275 +} 1.276 + 1.277 +nsresult nsNPAPIPluginInstance::Stop() 1.278 +{ 1.279 + PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance::Stop this=%p\n",this)); 1.280 + 1.281 + // Make sure the plugin didn't leave popups enabled. 1.282 + if (mPopupStates.Length() > 0) { 1.283 + nsCOMPtr<nsPIDOMWindow> window = GetDOMWindow(); 1.284 + 1.285 + if (window) { 1.286 + window->PopPopupControlState(openAbused); 1.287 + } 1.288 + } 1.289 + 1.290 + if (RUNNING != mRunning) { 1.291 + return NS_OK; 1.292 + } 1.293 + 1.294 + // clean up all outstanding timers 1.295 + for (uint32_t i = mTimers.Length(); i > 0; i--) 1.296 + UnscheduleTimer(mTimers[i - 1]->id); 1.297 + 1.298 + // If there's code from this plugin instance on the stack, delay the 1.299 + // destroy. 1.300 + if (PluginDestructionGuard::DelayDestroy(this)) { 1.301 + return NS_OK; 1.302 + } 1.303 + 1.304 + // Make sure we lock while we're writing to mRunning after we've 1.305 + // started as other threads might be checking that inside a lock. 1.306 + { 1.307 + AsyncCallbackAutoLock lock; 1.308 + mRunning = DESTROYING; 1.309 + mStopTime = TimeStamp::Now(); 1.310 + } 1.311 + 1.312 + OnPluginDestroy(&mNPP); 1.313 + 1.314 + // clean up open streams 1.315 + while (mStreamListeners.Length() > 0) { 1.316 + nsRefPtr<nsNPAPIPluginStreamListener> currentListener(mStreamListeners[0]); 1.317 + currentListener->CleanUpStream(NPRES_USER_BREAK); 1.318 + mStreamListeners.RemoveElement(currentListener); 1.319 + } 1.320 + 1.321 + if (!mPlugin || !mPlugin->GetLibrary()) 1.322 + return NS_ERROR_FAILURE; 1.323 + 1.324 + NPPluginFuncs* pluginFunctions = mPlugin->PluginFuncs(); 1.325 + 1.326 + NPError error = NPERR_GENERIC_ERROR; 1.327 + if (pluginFunctions->destroy) { 1.328 + NPSavedData *sdata = 0; 1.329 + 1.330 + NS_TRY_SAFE_CALL_RETURN(error, (*pluginFunctions->destroy)(&mNPP, &sdata), this, 1.331 + NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO); 1.332 + 1.333 + NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL, 1.334 + ("NPP Destroy called: this=%p, npp=%p, return=%d\n", this, &mNPP, error)); 1.335 + } 1.336 + mRunning = DESTROYED; 1.337 + 1.338 +#if MOZ_WIDGET_ANDROID 1.339 + for (uint32_t i = 0; i < mPostedEvents.Length(); i++) { 1.340 + mPostedEvents[i]->Cancel(); 1.341 + } 1.342 + 1.343 + mPostedEvents.Clear(); 1.344 +#endif 1.345 + 1.346 + nsJSNPRuntime::OnPluginDestroy(&mNPP); 1.347 + 1.348 + if (error != NPERR_NO_ERROR) 1.349 + return NS_ERROR_FAILURE; 1.350 + else 1.351 + return NS_OK; 1.352 +} 1.353 + 1.354 +already_AddRefed<nsPIDOMWindow> 1.355 +nsNPAPIPluginInstance::GetDOMWindow() 1.356 +{ 1.357 + if (!mOwner) 1.358 + return nullptr; 1.359 + 1.360 + nsRefPtr<nsPluginInstanceOwner> deathGrip(mOwner); 1.361 + 1.362 + nsCOMPtr<nsIDocument> doc; 1.363 + mOwner->GetDocument(getter_AddRefs(doc)); 1.364 + if (!doc) 1.365 + return nullptr; 1.366 + 1.367 + nsRefPtr<nsPIDOMWindow> window = doc->GetWindow(); 1.368 + 1.369 + return window.forget(); 1.370 +} 1.371 + 1.372 +nsresult 1.373 +nsNPAPIPluginInstance::GetTagType(nsPluginTagType *result) 1.374 +{ 1.375 + if (!mOwner) { 1.376 + return NS_ERROR_FAILURE; 1.377 + } 1.378 + 1.379 + return mOwner->GetTagType(result); 1.380 +} 1.381 + 1.382 +nsresult 1.383 +nsNPAPIPluginInstance::GetAttributes(uint16_t& n, const char*const*& names, 1.384 + const char*const*& values) 1.385 +{ 1.386 + if (!mOwner) { 1.387 + return NS_ERROR_FAILURE; 1.388 + } 1.389 + 1.390 + return mOwner->GetAttributes(n, names, values); 1.391 +} 1.392 + 1.393 +nsresult 1.394 +nsNPAPIPluginInstance::GetParameters(uint16_t& n, const char*const*& names, 1.395 + const char*const*& values) 1.396 +{ 1.397 + if (!mOwner) { 1.398 + return NS_ERROR_FAILURE; 1.399 + } 1.400 + 1.401 + return mOwner->GetParameters(n, names, values); 1.402 +} 1.403 + 1.404 +nsresult 1.405 +nsNPAPIPluginInstance::GetMode(int32_t *result) 1.406 +{ 1.407 + if (mOwner) 1.408 + return mOwner->GetMode(result); 1.409 + else 1.410 + return NS_ERROR_FAILURE; 1.411 +} 1.412 + 1.413 +nsTArray<nsNPAPIPluginStreamListener*>* 1.414 +nsNPAPIPluginInstance::StreamListeners() 1.415 +{ 1.416 + return &mStreamListeners; 1.417 +} 1.418 + 1.419 +nsTArray<nsPluginStreamListenerPeer*>* 1.420 +nsNPAPIPluginInstance::FileCachedStreamListeners() 1.421 +{ 1.422 + return &mFileCachedStreamListeners; 1.423 +} 1.424 + 1.425 +nsresult 1.426 +nsNPAPIPluginInstance::Start() 1.427 +{ 1.428 + if (mRunning == RUNNING) { 1.429 + return NS_OK; 1.430 + } 1.431 + 1.432 + PluginDestructionGuard guard(this); 1.433 + 1.434 + uint16_t count = 0; 1.435 + const char* const* names = nullptr; 1.436 + const char* const* values = nullptr; 1.437 + nsPluginTagType tagtype; 1.438 + nsresult rv = GetTagType(&tagtype); 1.439 + if (NS_SUCCEEDED(rv)) { 1.440 + // Note: If we failed to get the tag type, we may be a full page plugin, so no arguments 1.441 + rv = GetAttributes(count, names, values); 1.442 + NS_ENSURE_SUCCESS(rv, rv); 1.443 + 1.444 + // nsPluginTagType_Object or Applet may also have PARAM tags 1.445 + // Note: The arrays handed back by GetParameters() are 1.446 + // crafted specially to be directly behind the arrays from GetAttributes() 1.447 + // with a null entry as a separator. This is for 4.x backwards compatibility! 1.448 + // see bug 111008 for details 1.449 + if (tagtype != nsPluginTagType_Embed) { 1.450 + uint16_t pcount = 0; 1.451 + const char* const* pnames = nullptr; 1.452 + const char* const* pvalues = nullptr; 1.453 + if (NS_SUCCEEDED(GetParameters(pcount, pnames, pvalues))) { 1.454 + // Android expects an empty string as the separator instead of null 1.455 +#ifdef MOZ_WIDGET_ANDROID 1.456 + NS_ASSERTION(PL_strcmp(values[count], "") == 0, "attribute/parameter array not setup correctly for Android NPAPI plugins"); 1.457 +#else 1.458 + NS_ASSERTION(!values[count], "attribute/parameter array not setup correctly for NPAPI plugins"); 1.459 +#endif 1.460 + if (pcount) 1.461 + count += ++pcount; // if it's all setup correctly, then all we need is to 1.462 + // change the count (attrs + PARAM/blank + params) 1.463 + } 1.464 + } 1.465 + } 1.466 + 1.467 + int32_t mode; 1.468 + const char* mimetype; 1.469 + NPError error = NPERR_GENERIC_ERROR; 1.470 + 1.471 + GetMode(&mode); 1.472 + GetMIMEType(&mimetype); 1.473 + 1.474 + CheckJavaC2PJSObjectQuirk(count, names, values); 1.475 + 1.476 + // Some older versions of Flash have a bug in them 1.477 + // that causes the stack to become currupt if we 1.478 + // pass swliveconnect=1 in the NPP_NewProc arrays. 1.479 + // See bug 149336 (UNIX), bug 186287 (Mac) 1.480 + // 1.481 + // The code below disables the attribute unless 1.482 + // the environment variable: 1.483 + // MOZILLA_PLUGIN_DISABLE_FLASH_SWLIVECONNECT_HACK 1.484 + // is set. 1.485 + // 1.486 + // It is okay to disable this attribute because 1.487 + // back in 4.x, scripting required liveconnect to 1.488 + // start Java which was slow. Scripting no longer 1.489 + // requires starting Java and is quick plus controled 1.490 + // from the browser, so Flash now ignores this attribute. 1.491 + // 1.492 + // This code can not be put at the time of creating 1.493 + // the array because we may need to examine the 1.494 + // stream header to determine we want Flash. 1.495 + 1.496 + static const char flashMimeType[] = "application/x-shockwave-flash"; 1.497 + static const char blockedParam[] = "swliveconnect"; 1.498 + if (count && !PL_strcasecmp(mimetype, flashMimeType)) { 1.499 + static int cachedDisableHack = 0; 1.500 + if (!cachedDisableHack) { 1.501 + if (PR_GetEnv("MOZILLA_PLUGIN_DISABLE_FLASH_SWLIVECONNECT_HACK")) 1.502 + cachedDisableHack = -1; 1.503 + else 1.504 + cachedDisableHack = 1; 1.505 + } 1.506 + if (cachedDisableHack > 0) { 1.507 + for (uint16_t i=0; i<count; i++) { 1.508 + if (!PL_strcasecmp(names[i], blockedParam)) { 1.509 + // BIG FAT WARNIG: 1.510 + // I'm ugly casting |const char*| to |char*| and altering it 1.511 + // because I know we do malloc it values in 1.512 + // http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/layout/html/base/src/nsObjectFrame.cpp&rev=1.349&root=/cvsroot#3020 1.513 + // and free it at line #2096, so it couldn't be a const ptr to string literal 1.514 + char *val = (char*) values[i]; 1.515 + if (val && *val) { 1.516 + // we cannot just *val=0, it won't be free properly in such case 1.517 + val[0] = '0'; 1.518 + val[1] = 0; 1.519 + } 1.520 + break; 1.521 + } 1.522 + } 1.523 + } 1.524 + } 1.525 + 1.526 + bool oldVal = mInPluginInitCall; 1.527 + mInPluginInitCall = true; 1.528 + 1.529 + // Need this on the stack before calling NPP_New otherwise some callbacks that 1.530 + // the plugin may make could fail (NPN_HasProperty, for example). 1.531 + NPPAutoPusher autopush(&mNPP); 1.532 + 1.533 + if (!mPlugin) 1.534 + return NS_ERROR_FAILURE; 1.535 + 1.536 + PluginLibrary* library = mPlugin->GetLibrary(); 1.537 + if (!library) 1.538 + return NS_ERROR_FAILURE; 1.539 + 1.540 + // Mark this instance as running before calling NPP_New because the plugin may 1.541 + // call other NPAPI functions, like NPN_GetURLNotify, that assume this is set 1.542 + // before returning. If the plugin returns failure, we'll clear it out below. 1.543 + mRunning = RUNNING; 1.544 + 1.545 + nsresult newResult = library->NPP_New((char*)mimetype, &mNPP, (uint16_t)mode, 1.546 + count, (char**)names, (char**)values, 1.547 + nullptr, &error); 1.548 + mInPluginInitCall = oldVal; 1.549 + 1.550 + NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL, 1.551 + ("NPP New called: this=%p, npp=%p, mime=%s, mode=%d, argc=%d, return=%d\n", 1.552 + this, &mNPP, mimetype, mode, count, error)); 1.553 + 1.554 + if (NS_FAILED(newResult) || error != NPERR_NO_ERROR) { 1.555 + mRunning = DESTROYED; 1.556 + nsJSNPRuntime::OnPluginDestroy(&mNPP); 1.557 + return NS_ERROR_FAILURE; 1.558 + } 1.559 + 1.560 + return NS_OK; 1.561 +} 1.562 + 1.563 +nsresult nsNPAPIPluginInstance::SetWindow(NPWindow* window) 1.564 +{ 1.565 + // NPAPI plugins don't want a SetWindow(nullptr). 1.566 + if (!window || RUNNING != mRunning) 1.567 + return NS_OK; 1.568 + 1.569 +#if MOZ_WIDGET_GTK 1.570 + // bug 108347, flash plugin on linux doesn't like window->width <= 1.571 + // 0, but Java needs wants this call. 1.572 + if (!nsPluginHost::IsJavaMIMEType(mMIMEType) && window->type == NPWindowTypeWindow && 1.573 + (window->width <= 0 || window->height <= 0)) { 1.574 + return NS_OK; 1.575 + } 1.576 +#endif 1.577 + 1.578 + if (!mPlugin || !mPlugin->GetLibrary()) 1.579 + return NS_ERROR_FAILURE; 1.580 + 1.581 + NPPluginFuncs* pluginFunctions = mPlugin->PluginFuncs(); 1.582 + 1.583 + if (pluginFunctions->setwindow) { 1.584 + PluginDestructionGuard guard(this); 1.585 + 1.586 + // XXX Turns out that NPPluginWindow and NPWindow are structurally 1.587 + // identical (on purpose!), so there's no need to make a copy. 1.588 + 1.589 + PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance::SetWindow (about to call it) this=%p\n",this)); 1.590 + 1.591 + bool oldVal = mInPluginInitCall; 1.592 + mInPluginInitCall = true; 1.593 + 1.594 + NPPAutoPusher nppPusher(&mNPP); 1.595 + 1.596 + DebugOnly<NPError> error; 1.597 + NS_TRY_SAFE_CALL_RETURN(error, (*pluginFunctions->setwindow)(&mNPP, (NPWindow*)window), this, 1.598 + NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO); 1.599 + 1.600 + mInPluginInitCall = oldVal; 1.601 + 1.602 + NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL, 1.603 + ("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", 1.604 + this, window->x, window->y, window->width, window->height, 1.605 + window->clipRect.top, window->clipRect.bottom, window->clipRect.left, window->clipRect.right, (NPError)error)); 1.606 + } 1.607 + return NS_OK; 1.608 +} 1.609 + 1.610 +nsresult 1.611 +nsNPAPIPluginInstance::NewStreamFromPlugin(const char* type, const char* target, 1.612 + nsIOutputStream* *result) 1.613 +{ 1.614 + nsPluginStreamToFile* stream = new nsPluginStreamToFile(target, mOwner); 1.615 + if (!stream) 1.616 + return NS_ERROR_OUT_OF_MEMORY; 1.617 + 1.618 + return stream->QueryInterface(kIOutputStreamIID, (void**)result); 1.619 +} 1.620 + 1.621 +nsresult 1.622 +nsNPAPIPluginInstance::NewStreamListener(const char* aURL, void* notifyData, 1.623 + nsNPAPIPluginStreamListener** listener) 1.624 +{ 1.625 + nsRefPtr<nsNPAPIPluginStreamListener> sl = new nsNPAPIPluginStreamListener(this, notifyData, aURL); 1.626 + 1.627 + mStreamListeners.AppendElement(sl); 1.628 + 1.629 + sl.forget(listener); 1.630 + 1.631 + return NS_OK; 1.632 +} 1.633 + 1.634 +nsresult nsNPAPIPluginInstance::Print(NPPrint* platformPrint) 1.635 +{ 1.636 + NS_ENSURE_TRUE(platformPrint, NS_ERROR_NULL_POINTER); 1.637 + 1.638 + PluginDestructionGuard guard(this); 1.639 + 1.640 + if (!mPlugin || !mPlugin->GetLibrary()) 1.641 + return NS_ERROR_FAILURE; 1.642 + 1.643 + NPPluginFuncs* pluginFunctions = mPlugin->PluginFuncs(); 1.644 + 1.645 + NPPrint* thePrint = (NPPrint *)platformPrint; 1.646 + 1.647 + // to be compatible with the older SDK versions and to match what 1.648 + // NPAPI and other browsers do, overwrite |window.type| field with one 1.649 + // more copy of |platformPrint|. See bug 113264 1.650 + uint16_t sdkmajorversion = (pluginFunctions->version & 0xff00)>>8; 1.651 + uint16_t sdkminorversion = pluginFunctions->version & 0x00ff; 1.652 + if ((sdkmajorversion == 0) && (sdkminorversion < 11)) { 1.653 + // Let's copy platformPrint bytes over to where it was supposed to be 1.654 + // in older versions -- four bytes towards the beginning of the struct 1.655 + // but we should be careful about possible misalignments 1.656 + if (sizeof(NPWindowType) >= sizeof(void *)) { 1.657 + void* source = thePrint->print.embedPrint.platformPrint; 1.658 + void** destination = (void **)&(thePrint->print.embedPrint.window.type); 1.659 + *destination = source; 1.660 + } else { 1.661 + NS_ERROR("Incompatible OS for assignment"); 1.662 + } 1.663 + } 1.664 + 1.665 + if (pluginFunctions->print) 1.666 + NS_TRY_SAFE_CALL_VOID((*pluginFunctions->print)(&mNPP, thePrint), this, 1.667 + NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO); 1.668 + 1.669 + NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL, 1.670 + ("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", 1.671 + this, 1.672 + platformPrint->print.embedPrint.platformPrint, 1.673 + platformPrint->print.embedPrint.window.x, 1.674 + platformPrint->print.embedPrint.window.y, 1.675 + platformPrint->print.embedPrint.window.width, 1.676 + platformPrint->print.embedPrint.window.height, 1.677 + platformPrint->print.embedPrint.window.clipRect.top, 1.678 + platformPrint->print.embedPrint.window.clipRect.bottom, 1.679 + platformPrint->print.embedPrint.window.clipRect.left, 1.680 + platformPrint->print.embedPrint.window.clipRect.right)); 1.681 + 1.682 + return NS_OK; 1.683 +} 1.684 + 1.685 +nsresult nsNPAPIPluginInstance::HandleEvent(void* event, int16_t* result, 1.686 + NSPluginCallReentry aSafeToReenterGecko) 1.687 +{ 1.688 + if (RUNNING != mRunning) 1.689 + return NS_OK; 1.690 + 1.691 + if (!event) 1.692 + return NS_ERROR_FAILURE; 1.693 + 1.694 + PluginDestructionGuard guard(this); 1.695 + 1.696 + if (!mPlugin || !mPlugin->GetLibrary()) 1.697 + return NS_ERROR_FAILURE; 1.698 + 1.699 + NPPluginFuncs* pluginFunctions = mPlugin->PluginFuncs(); 1.700 + 1.701 + int16_t tmpResult = kNPEventNotHandled; 1.702 + 1.703 + if (pluginFunctions->event) { 1.704 + mCurrentPluginEvent = event; 1.705 +#if defined(XP_WIN) 1.706 + NS_TRY_SAFE_CALL_RETURN(tmpResult, (*pluginFunctions->event)(&mNPP, event), this, 1.707 + aSafeToReenterGecko); 1.708 +#else 1.709 + MAIN_THREAD_JNI_REF_GUARD; 1.710 + tmpResult = (*pluginFunctions->event)(&mNPP, event); 1.711 +#endif 1.712 + NPP_PLUGIN_LOG(PLUGIN_LOG_NOISY, 1.713 + ("NPP HandleEvent called: this=%p, npp=%p, event=%p, return=%d\n", 1.714 + this, &mNPP, event, tmpResult)); 1.715 + 1.716 + if (result) 1.717 + *result = tmpResult; 1.718 + mCurrentPluginEvent = nullptr; 1.719 + } 1.720 + 1.721 + return NS_OK; 1.722 +} 1.723 + 1.724 +nsresult nsNPAPIPluginInstance::GetValueFromPlugin(NPPVariable variable, void* value) 1.725 +{ 1.726 + if (!mPlugin || !mPlugin->GetLibrary()) 1.727 + return NS_ERROR_FAILURE; 1.728 + 1.729 + NPPluginFuncs* pluginFunctions = mPlugin->PluginFuncs(); 1.730 + 1.731 + nsresult rv = NS_ERROR_FAILURE; 1.732 + 1.733 + if (pluginFunctions->getvalue && RUNNING == mRunning) { 1.734 + PluginDestructionGuard guard(this); 1.735 + 1.736 + NPError pluginError = NPERR_GENERIC_ERROR; 1.737 + NS_TRY_SAFE_CALL_RETURN(pluginError, (*pluginFunctions->getvalue)(&mNPP, variable, value), this, 1.738 + NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO); 1.739 + NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL, 1.740 + ("NPP GetValue called: this=%p, npp=%p, var=%d, value=%d, return=%d\n", 1.741 + this, &mNPP, variable, value, pluginError)); 1.742 + 1.743 + if (pluginError == NPERR_NO_ERROR) { 1.744 + rv = NS_OK; 1.745 + } 1.746 + } 1.747 + 1.748 + return rv; 1.749 +} 1.750 + 1.751 +nsNPAPIPlugin* nsNPAPIPluginInstance::GetPlugin() 1.752 +{ 1.753 + return mPlugin; 1.754 +} 1.755 + 1.756 +nsresult nsNPAPIPluginInstance::GetNPP(NPP* aNPP) 1.757 +{ 1.758 + if (aNPP) 1.759 + *aNPP = &mNPP; 1.760 + else 1.761 + return NS_ERROR_NULL_POINTER; 1.762 + 1.763 + return NS_OK; 1.764 +} 1.765 + 1.766 +NPError nsNPAPIPluginInstance::SetWindowless(bool aWindowless) 1.767 +{ 1.768 + mWindowless = aWindowless; 1.769 + 1.770 + if (mMIMEType) { 1.771 + // bug 558434 - Prior to 3.6.4, we assumed windowless was transparent. 1.772 + // Silverlight apparently relied on this quirk, so we default to 1.773 + // transparent unless they specify otherwise after setting the windowless 1.774 + // property. (Last tested version: sl 4.0). 1.775 + // Changes to this code should be matched with changes in 1.776 + // PluginInstanceChild::InitQuirksMode. 1.777 + NS_NAMED_LITERAL_CSTRING(silverlight, "application/x-silverlight"); 1.778 + if (!PL_strncasecmp(mMIMEType, silverlight.get(), silverlight.Length())) { 1.779 + mTransparent = true; 1.780 + } 1.781 + } 1.782 + 1.783 + return NPERR_NO_ERROR; 1.784 +} 1.785 + 1.786 +NPError nsNPAPIPluginInstance::SetTransparent(bool aTransparent) 1.787 +{ 1.788 + mTransparent = aTransparent; 1.789 + return NPERR_NO_ERROR; 1.790 +} 1.791 + 1.792 +NPError nsNPAPIPluginInstance::SetUsesDOMForCursor(bool aUsesDOMForCursor) 1.793 +{ 1.794 + mUsesDOMForCursor = aUsesDOMForCursor; 1.795 + return NPERR_NO_ERROR; 1.796 +} 1.797 + 1.798 +bool 1.799 +nsNPAPIPluginInstance::UsesDOMForCursor() 1.800 +{ 1.801 + return mUsesDOMForCursor; 1.802 +} 1.803 + 1.804 +void nsNPAPIPluginInstance::SetDrawingModel(NPDrawingModel aModel) 1.805 +{ 1.806 + mDrawingModel = aModel; 1.807 +} 1.808 + 1.809 +void nsNPAPIPluginInstance::RedrawPlugin() 1.810 +{ 1.811 + mOwner->RedrawPlugin(); 1.812 +} 1.813 + 1.814 +#if defined(XP_MACOSX) 1.815 +void nsNPAPIPluginInstance::SetEventModel(NPEventModel aModel) 1.816 +{ 1.817 + // the event model needs to be set for the object frame immediately 1.818 + if (!mOwner) { 1.819 + NS_WARNING("Trying to set event model without a plugin instance owner!"); 1.820 + return; 1.821 + } 1.822 + 1.823 + mOwner->SetEventModel(aModel); 1.824 +} 1.825 +#endif 1.826 + 1.827 +#if defined(MOZ_WIDGET_ANDROID) 1.828 + 1.829 +static void SendLifecycleEvent(nsNPAPIPluginInstance* aInstance, uint32_t aAction) 1.830 +{ 1.831 + ANPEvent event; 1.832 + event.inSize = sizeof(ANPEvent); 1.833 + event.eventType = kLifecycle_ANPEventType; 1.834 + event.data.lifecycle.action = aAction; 1.835 + aInstance->HandleEvent(&event, nullptr); 1.836 +} 1.837 + 1.838 +void nsNPAPIPluginInstance::NotifyForeground(bool aForeground) 1.839 +{ 1.840 + PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance::SetForeground this=%p\n foreground=%d",this, aForeground)); 1.841 + if (RUNNING != mRunning) 1.842 + return; 1.843 + 1.844 + SendLifecycleEvent(this, aForeground ? kResume_ANPLifecycleAction : kPause_ANPLifecycleAction); 1.845 +} 1.846 + 1.847 +void nsNPAPIPluginInstance::NotifyOnScreen(bool aOnScreen) 1.848 +{ 1.849 + PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance::SetOnScreen this=%p\n onScreen=%d",this, aOnScreen)); 1.850 + if (RUNNING != mRunning || mOnScreen == aOnScreen) 1.851 + return; 1.852 + 1.853 + mOnScreen = aOnScreen; 1.854 + SendLifecycleEvent(this, aOnScreen ? kOnScreen_ANPLifecycleAction : kOffScreen_ANPLifecycleAction); 1.855 +} 1.856 + 1.857 +void nsNPAPIPluginInstance::MemoryPressure() 1.858 +{ 1.859 + PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance::MemoryPressure this=%p\n",this)); 1.860 + if (RUNNING != mRunning) 1.861 + return; 1.862 + 1.863 + SendLifecycleEvent(this, kFreeMemory_ANPLifecycleAction); 1.864 +} 1.865 + 1.866 +void nsNPAPIPluginInstance::NotifyFullScreen(bool aFullScreen) 1.867 +{ 1.868 + PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance::NotifyFullScreen this=%p\n",this)); 1.869 + 1.870 + if (RUNNING != mRunning || mFullScreen == aFullScreen) 1.871 + return; 1.872 + 1.873 + mFullScreen = aFullScreen; 1.874 + SendLifecycleEvent(this, mFullScreen ? kEnterFullScreen_ANPLifecycleAction : kExitFullScreen_ANPLifecycleAction); 1.875 + 1.876 + if (mFullScreen && mFullScreenOrientation != dom::eScreenOrientation_None) { 1.877 + mozilla::widget::android::GeckoAppShell::LockScreenOrientation(mFullScreenOrientation); 1.878 + } 1.879 +} 1.880 + 1.881 +void nsNPAPIPluginInstance::NotifySize(nsIntSize size) 1.882 +{ 1.883 + if (kOpenGL_ANPDrawingModel != GetANPDrawingModel() || 1.884 + size == mCurrentSize) 1.885 + return; 1.886 + 1.887 + mCurrentSize = size; 1.888 + 1.889 + ANPEvent event; 1.890 + event.inSize = sizeof(ANPEvent); 1.891 + event.eventType = kDraw_ANPEventType; 1.892 + event.data.draw.model = kOpenGL_ANPDrawingModel; 1.893 + event.data.draw.data.surfaceSize.width = size.width; 1.894 + event.data.draw.data.surfaceSize.height = size.height; 1.895 + 1.896 + HandleEvent(&event, nullptr); 1.897 +} 1.898 + 1.899 +void nsNPAPIPluginInstance::SetANPDrawingModel(uint32_t aModel) 1.900 +{ 1.901 + mANPDrawingModel = aModel; 1.902 +} 1.903 + 1.904 +void* nsNPAPIPluginInstance::GetJavaSurface() 1.905 +{ 1.906 + void* surface = nullptr; 1.907 + nsresult rv = GetValueFromPlugin(kJavaSurface_ANPGetValue, &surface); 1.908 + if (NS_FAILED(rv)) 1.909 + return nullptr; 1.910 + 1.911 + return surface; 1.912 +} 1.913 + 1.914 +void nsNPAPIPluginInstance::PostEvent(void* event) 1.915 +{ 1.916 + PluginEventRunnable *r = new PluginEventRunnable(this, (ANPEvent*)event); 1.917 + mPostedEvents.AppendElement(nsRefPtr<PluginEventRunnable>(r)); 1.918 + 1.919 + NS_DispatchToMainThread(r); 1.920 +} 1.921 + 1.922 +void nsNPAPIPluginInstance::SetFullScreenOrientation(uint32_t orientation) 1.923 +{ 1.924 + if (mFullScreenOrientation == orientation) 1.925 + return; 1.926 + 1.927 + uint32_t oldOrientation = mFullScreenOrientation; 1.928 + mFullScreenOrientation = orientation; 1.929 + 1.930 + if (mFullScreen) { 1.931 + // We're already fullscreen so immediately apply the orientation change 1.932 + 1.933 + if (mFullScreenOrientation != dom::eScreenOrientation_None) { 1.934 + mozilla::widget::android::GeckoAppShell::LockScreenOrientation(mFullScreenOrientation); 1.935 + } else if (oldOrientation != dom::eScreenOrientation_None) { 1.936 + // We applied an orientation when we entered fullscreen, but 1.937 + // we don't want it anymore 1.938 + mozilla::widget::android::GeckoAppShell::UnlockScreenOrientation(); 1.939 + } 1.940 + } 1.941 +} 1.942 + 1.943 +void nsNPAPIPluginInstance::PopPostedEvent(PluginEventRunnable* r) 1.944 +{ 1.945 + mPostedEvents.RemoveElement(r); 1.946 +} 1.947 + 1.948 +void nsNPAPIPluginInstance::SetWakeLock(bool aLocked) 1.949 +{ 1.950 + if (aLocked == mWakeLocked) 1.951 + return; 1.952 + 1.953 + mWakeLocked = aLocked; 1.954 + hal::ModifyWakeLock(NS_LITERAL_STRING("nsNPAPIPluginInstance"), 1.955 + mWakeLocked ? hal::WAKE_LOCK_ADD_ONE : hal::WAKE_LOCK_REMOVE_ONE, 1.956 + hal::WAKE_LOCK_NO_CHANGE); 1.957 +} 1.958 + 1.959 +void nsNPAPIPluginInstance::EnsureSharedTexture() 1.960 +{ 1.961 + if (!mContentTexture) 1.962 + mContentTexture = new SharedPluginTexture(); 1.963 +} 1.964 + 1.965 +GLContext* nsNPAPIPluginInstance::GLContext() 1.966 +{ 1.967 + if (!EnsureGLContext()) 1.968 + return nullptr; 1.969 + 1.970 + return sPluginContext; 1.971 +} 1.972 + 1.973 +nsNPAPIPluginInstance::TextureInfo nsNPAPIPluginInstance::LockContentTexture() 1.974 +{ 1.975 + EnsureSharedTexture(); 1.976 + return mContentTexture->Lock(); 1.977 +} 1.978 + 1.979 +void nsNPAPIPluginInstance::ReleaseContentTexture(nsNPAPIPluginInstance::TextureInfo& aTextureInfo) 1.980 +{ 1.981 + EnsureSharedTexture(); 1.982 + mContentTexture->Release(aTextureInfo); 1.983 +} 1.984 + 1.985 +nsSurfaceTexture* nsNPAPIPluginInstance::CreateSurfaceTexture() 1.986 +{ 1.987 + if (!EnsureGLContext()) 1.988 + return nullptr; 1.989 + 1.990 + GLuint texture = TexturePoolOGL::AcquireTexture(); 1.991 + if (!texture) 1.992 + return nullptr; 1.993 + 1.994 + nsSurfaceTexture* surface = nsSurfaceTexture::Create(texture); 1.995 + if (!surface) 1.996 + return nullptr; 1.997 + 1.998 + nsCOMPtr<nsIRunnable> frameCallback = NS_NewRunnableMethod(this, &nsNPAPIPluginInstance::OnSurfaceTextureFrameAvailable); 1.999 + surface->SetFrameAvailableCallback(frameCallback); 1.1000 + return surface; 1.1001 +} 1.1002 + 1.1003 +void nsNPAPIPluginInstance::OnSurfaceTextureFrameAvailable() 1.1004 +{ 1.1005 + if (mRunning == RUNNING && mOwner) 1.1006 + AndroidBridge::Bridge()->ScheduleComposite(); 1.1007 +} 1.1008 + 1.1009 +void* nsNPAPIPluginInstance::AcquireContentWindow() 1.1010 +{ 1.1011 + if (!mContentSurface) { 1.1012 + mContentSurface = CreateSurfaceTexture(); 1.1013 + 1.1014 + if (!mContentSurface) 1.1015 + return nullptr; 1.1016 + } 1.1017 + 1.1018 + return mContentSurface->GetNativeWindow(); 1.1019 +} 1.1020 + 1.1021 +SharedTextureHandle nsNPAPIPluginInstance::CreateSharedHandle() 1.1022 +{ 1.1023 + if (mContentTexture) { 1.1024 + return mContentTexture->CreateSharedHandle(); 1.1025 + } else if (mContentSurface) { 1.1026 + EnsureGLContext(); 1.1027 + return gl::CreateSharedHandle(sPluginContext, 1.1028 + gl::SharedTextureShareType::SameProcess, 1.1029 + mContentSurface, 1.1030 + gl::SharedTextureBufferType::SurfaceTexture); 1.1031 + } else return 0; 1.1032 +} 1.1033 + 1.1034 +void* nsNPAPIPluginInstance::AcquireVideoWindow() 1.1035 +{ 1.1036 + nsSurfaceTexture* surface = CreateSurfaceTexture(); 1.1037 + if (!surface) 1.1038 + return nullptr; 1.1039 + 1.1040 + VideoInfo* info = new VideoInfo(surface); 1.1041 + 1.1042 + void* window = info->mSurfaceTexture->GetNativeWindow(); 1.1043 + mVideos.insert(std::pair<void*, VideoInfo*>(window, info)); 1.1044 + 1.1045 + return window; 1.1046 +} 1.1047 + 1.1048 +void nsNPAPIPluginInstance::ReleaseVideoWindow(void* window) 1.1049 +{ 1.1050 + std::map<void*, VideoInfo*>::iterator it = mVideos.find(window); 1.1051 + if (it == mVideos.end()) 1.1052 + return; 1.1053 + 1.1054 + delete it->second; 1.1055 + mVideos.erase(window); 1.1056 +} 1.1057 + 1.1058 +void nsNPAPIPluginInstance::SetVideoDimensions(void* window, gfxRect aDimensions) 1.1059 +{ 1.1060 + std::map<void*, VideoInfo*>::iterator it; 1.1061 + 1.1062 + it = mVideos.find(window); 1.1063 + if (it == mVideos.end()) 1.1064 + return; 1.1065 + 1.1066 + it->second->mDimensions = aDimensions; 1.1067 +} 1.1068 + 1.1069 +void nsNPAPIPluginInstance::GetVideos(nsTArray<VideoInfo*>& aVideos) 1.1070 +{ 1.1071 + std::map<void*, VideoInfo*>::iterator it; 1.1072 + for (it = mVideos.begin(); it != mVideos.end(); it++) 1.1073 + aVideos.AppendElement(it->second); 1.1074 +} 1.1075 + 1.1076 +void nsNPAPIPluginInstance::SetInverted(bool aInverted) 1.1077 +{ 1.1078 + if (aInverted == mInverted) 1.1079 + return; 1.1080 + 1.1081 + mInverted = aInverted; 1.1082 +} 1.1083 + 1.1084 +nsNPAPIPluginInstance* nsNPAPIPluginInstance::GetFromNPP(NPP npp) 1.1085 +{ 1.1086 + std::map<NPP, nsNPAPIPluginInstance*>::iterator it; 1.1087 + 1.1088 + it = sPluginNPPMap.find(npp); 1.1089 + if (it == sPluginNPPMap.end()) 1.1090 + return nullptr; 1.1091 + 1.1092 + return it->second; 1.1093 +} 1.1094 + 1.1095 +#endif 1.1096 + 1.1097 +nsresult nsNPAPIPluginInstance::GetDrawingModel(int32_t* aModel) 1.1098 +{ 1.1099 +#if defined(XP_MACOSX) 1.1100 + *aModel = (int32_t)mDrawingModel; 1.1101 + return NS_OK; 1.1102 +#else 1.1103 + return NS_ERROR_FAILURE; 1.1104 +#endif 1.1105 +} 1.1106 + 1.1107 +nsresult nsNPAPIPluginInstance::IsRemoteDrawingCoreAnimation(bool* aDrawing) 1.1108 +{ 1.1109 +#ifdef XP_MACOSX 1.1110 + if (!mPlugin) 1.1111 + return NS_ERROR_FAILURE; 1.1112 + 1.1113 + PluginLibrary* library = mPlugin->GetLibrary(); 1.1114 + if (!library) 1.1115 + return NS_ERROR_FAILURE; 1.1116 + 1.1117 + return library->IsRemoteDrawingCoreAnimation(&mNPP, aDrawing); 1.1118 +#else 1.1119 + return NS_ERROR_FAILURE; 1.1120 +#endif 1.1121 +} 1.1122 + 1.1123 +nsresult nsNPAPIPluginInstance::ContentsScaleFactorChanged(double aContentsScaleFactor) 1.1124 +{ 1.1125 +#ifdef XP_MACOSX 1.1126 + if (!mPlugin) 1.1127 + return NS_ERROR_FAILURE; 1.1128 + 1.1129 + PluginLibrary* library = mPlugin->GetLibrary(); 1.1130 + if (!library) 1.1131 + return NS_ERROR_FAILURE; 1.1132 + 1.1133 + // We only need to call this if the plugin is running OOP. 1.1134 + if (!library->IsOOP()) 1.1135 + return NS_OK; 1.1136 + 1.1137 + return library->ContentsScaleFactorChanged(&mNPP, aContentsScaleFactor); 1.1138 +#else 1.1139 + return NS_ERROR_FAILURE; 1.1140 +#endif 1.1141 +} 1.1142 + 1.1143 +nsresult 1.1144 +nsNPAPIPluginInstance::GetJSObject(JSContext *cx, JSObject** outObject) 1.1145 +{ 1.1146 + if (mHaveJavaC2PJSObjectQuirk) { 1.1147 + return NS_ERROR_FAILURE; 1.1148 + } 1.1149 + 1.1150 + NPObject *npobj = nullptr; 1.1151 + nsresult rv = GetValueFromPlugin(NPPVpluginScriptableNPObject, &npobj); 1.1152 + if (NS_FAILED(rv) || !npobj) 1.1153 + return NS_ERROR_FAILURE; 1.1154 + 1.1155 + *outObject = nsNPObjWrapper::GetNewOrUsed(&mNPP, cx, npobj); 1.1156 + 1.1157 + _releaseobject(npobj); 1.1158 + 1.1159 + return NS_OK; 1.1160 +} 1.1161 + 1.1162 +void 1.1163 +nsNPAPIPluginInstance::SetCached(bool aCache) 1.1164 +{ 1.1165 + mCached = aCache; 1.1166 +} 1.1167 + 1.1168 +bool 1.1169 +nsNPAPIPluginInstance::ShouldCache() 1.1170 +{ 1.1171 + return mCached; 1.1172 +} 1.1173 + 1.1174 +nsresult 1.1175 +nsNPAPIPluginInstance::IsWindowless(bool* isWindowless) 1.1176 +{ 1.1177 +#ifdef MOZ_WIDGET_ANDROID 1.1178 + // On android, pre-honeycomb, all plugins are treated as windowless. 1.1179 + *isWindowless = true; 1.1180 +#else 1.1181 + *isWindowless = mWindowless; 1.1182 +#endif 1.1183 + return NS_OK; 1.1184 +} 1.1185 + 1.1186 +class MOZ_STACK_CLASS AutoPluginLibraryCall 1.1187 +{ 1.1188 +public: 1.1189 + AutoPluginLibraryCall(nsNPAPIPluginInstance* aThis) 1.1190 + : mThis(aThis), mGuard(aThis), mLibrary(nullptr) 1.1191 + { 1.1192 + nsNPAPIPlugin* plugin = mThis->GetPlugin(); 1.1193 + if (plugin) 1.1194 + mLibrary = plugin->GetLibrary(); 1.1195 + } 1.1196 + operator bool() { return !!mLibrary; } 1.1197 + PluginLibrary* operator->() { return mLibrary; } 1.1198 + 1.1199 +private: 1.1200 + nsNPAPIPluginInstance* mThis; 1.1201 + PluginDestructionGuard mGuard; 1.1202 + PluginLibrary* mLibrary; 1.1203 +}; 1.1204 + 1.1205 +nsresult 1.1206 +nsNPAPIPluginInstance::AsyncSetWindow(NPWindow* window) 1.1207 +{ 1.1208 + if (RUNNING != mRunning) 1.1209 + return NS_OK; 1.1210 + 1.1211 + AutoPluginLibraryCall library(this); 1.1212 + if (!library) 1.1213 + return NS_ERROR_FAILURE; 1.1214 + 1.1215 + return library->AsyncSetWindow(&mNPP, window); 1.1216 +} 1.1217 + 1.1218 +nsresult 1.1219 +nsNPAPIPluginInstance::GetImageContainer(ImageContainer**aContainer) 1.1220 +{ 1.1221 + *aContainer = nullptr; 1.1222 + 1.1223 + if (RUNNING != mRunning) 1.1224 + return NS_OK; 1.1225 + 1.1226 + AutoPluginLibraryCall library(this); 1.1227 + return !library ? NS_ERROR_FAILURE : library->GetImageContainer(&mNPP, aContainer); 1.1228 +} 1.1229 + 1.1230 +nsresult 1.1231 +nsNPAPIPluginInstance::GetImageSize(nsIntSize* aSize) 1.1232 +{ 1.1233 + *aSize = nsIntSize(0, 0); 1.1234 + 1.1235 + if (RUNNING != mRunning) 1.1236 + return NS_OK; 1.1237 + 1.1238 + AutoPluginLibraryCall library(this); 1.1239 + return !library ? NS_ERROR_FAILURE : library->GetImageSize(&mNPP, aSize); 1.1240 +} 1.1241 + 1.1242 +nsresult 1.1243 +nsNPAPIPluginInstance::NotifyPainted(void) 1.1244 +{ 1.1245 + NS_NOTREACHED("Dead code, shouldn't be called."); 1.1246 + return NS_ERROR_NOT_IMPLEMENTED; 1.1247 +} 1.1248 + 1.1249 +nsresult 1.1250 +nsNPAPIPluginInstance::GetIsOOP(bool* aIsAsync) 1.1251 +{ 1.1252 + AutoPluginLibraryCall library(this); 1.1253 + if (!library) 1.1254 + return NS_ERROR_FAILURE; 1.1255 + 1.1256 + *aIsAsync = library->IsOOP(); 1.1257 + return NS_OK; 1.1258 +} 1.1259 + 1.1260 +nsresult 1.1261 +nsNPAPIPluginInstance::SetBackgroundUnknown() 1.1262 +{ 1.1263 + if (RUNNING != mRunning) 1.1264 + return NS_OK; 1.1265 + 1.1266 + AutoPluginLibraryCall library(this); 1.1267 + if (!library) 1.1268 + return NS_ERROR_FAILURE; 1.1269 + 1.1270 + return library->SetBackgroundUnknown(&mNPP); 1.1271 +} 1.1272 + 1.1273 +nsresult 1.1274 +nsNPAPIPluginInstance::BeginUpdateBackground(nsIntRect* aRect, 1.1275 + gfxContext** aContext) 1.1276 +{ 1.1277 + if (RUNNING != mRunning) 1.1278 + return NS_OK; 1.1279 + 1.1280 + AutoPluginLibraryCall library(this); 1.1281 + if (!library) 1.1282 + return NS_ERROR_FAILURE; 1.1283 + 1.1284 + return library->BeginUpdateBackground(&mNPP, *aRect, aContext); 1.1285 +} 1.1286 + 1.1287 +nsresult 1.1288 +nsNPAPIPluginInstance::EndUpdateBackground(gfxContext* aContext, 1.1289 + nsIntRect* aRect) 1.1290 +{ 1.1291 + if (RUNNING != mRunning) 1.1292 + return NS_OK; 1.1293 + 1.1294 + AutoPluginLibraryCall library(this); 1.1295 + if (!library) 1.1296 + return NS_ERROR_FAILURE; 1.1297 + 1.1298 + return library->EndUpdateBackground(&mNPP, aContext, *aRect); 1.1299 +} 1.1300 + 1.1301 +nsresult 1.1302 +nsNPAPIPluginInstance::IsTransparent(bool* isTransparent) 1.1303 +{ 1.1304 + *isTransparent = mTransparent; 1.1305 + return NS_OK; 1.1306 +} 1.1307 + 1.1308 +nsresult 1.1309 +nsNPAPIPluginInstance::GetFormValue(nsAString& aValue) 1.1310 +{ 1.1311 + aValue.Truncate(); 1.1312 + 1.1313 + char *value = nullptr; 1.1314 + nsresult rv = GetValueFromPlugin(NPPVformValue, &value); 1.1315 + if (NS_FAILED(rv) || !value) 1.1316 + return NS_ERROR_FAILURE; 1.1317 + 1.1318 + CopyUTF8toUTF16(value, aValue); 1.1319 + 1.1320 + // NPPVformValue allocates with NPN_MemAlloc(), which uses 1.1321 + // nsMemory. 1.1322 + nsMemory::Free(value); 1.1323 + 1.1324 + return NS_OK; 1.1325 +} 1.1326 + 1.1327 +nsresult 1.1328 +nsNPAPIPluginInstance::PushPopupsEnabledState(bool aEnabled) 1.1329 +{ 1.1330 + nsCOMPtr<nsPIDOMWindow> window = GetDOMWindow(); 1.1331 + if (!window) 1.1332 + return NS_ERROR_FAILURE; 1.1333 + 1.1334 + PopupControlState oldState = 1.1335 + window->PushPopupControlState(aEnabled ? openAllowed : openAbused, 1.1336 + true); 1.1337 + 1.1338 + if (!mPopupStates.AppendElement(oldState)) { 1.1339 + // Appending to our state stack failed, pop what we just pushed. 1.1340 + window->PopPopupControlState(oldState); 1.1341 + return NS_ERROR_FAILURE; 1.1342 + } 1.1343 + 1.1344 + return NS_OK; 1.1345 +} 1.1346 + 1.1347 +nsresult 1.1348 +nsNPAPIPluginInstance::PopPopupsEnabledState() 1.1349 +{ 1.1350 + int32_t last = mPopupStates.Length() - 1; 1.1351 + 1.1352 + if (last < 0) { 1.1353 + // Nothing to pop. 1.1354 + return NS_OK; 1.1355 + } 1.1356 + 1.1357 + nsCOMPtr<nsPIDOMWindow> window = GetDOMWindow(); 1.1358 + if (!window) 1.1359 + return NS_ERROR_FAILURE; 1.1360 + 1.1361 + PopupControlState &oldState = mPopupStates[last]; 1.1362 + 1.1363 + window->PopPopupControlState(oldState); 1.1364 + 1.1365 + mPopupStates.RemoveElementAt(last); 1.1366 + 1.1367 + return NS_OK; 1.1368 +} 1.1369 + 1.1370 +nsresult 1.1371 +nsNPAPIPluginInstance::GetPluginAPIVersion(uint16_t* version) 1.1372 +{ 1.1373 + NS_ENSURE_ARG_POINTER(version); 1.1374 + 1.1375 + if (!mPlugin) 1.1376 + return NS_ERROR_FAILURE; 1.1377 + 1.1378 + if (!mPlugin->GetLibrary()) 1.1379 + return NS_ERROR_FAILURE; 1.1380 + 1.1381 + NPPluginFuncs* pluginFunctions = mPlugin->PluginFuncs(); 1.1382 + 1.1383 + *version = pluginFunctions->version; 1.1384 + 1.1385 + return NS_OK; 1.1386 +} 1.1387 + 1.1388 +nsresult 1.1389 +nsNPAPIPluginInstance::PrivateModeStateChanged(bool enabled) 1.1390 +{ 1.1391 + if (RUNNING != mRunning) 1.1392 + return NS_OK; 1.1393 + 1.1394 + PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance informing plugin of private mode state change this=%p\n",this)); 1.1395 + 1.1396 + if (!mPlugin || !mPlugin->GetLibrary()) 1.1397 + return NS_ERROR_FAILURE; 1.1398 + 1.1399 + NPPluginFuncs* pluginFunctions = mPlugin->PluginFuncs(); 1.1400 + 1.1401 + if (!pluginFunctions->setvalue) 1.1402 + return NS_ERROR_FAILURE; 1.1403 + 1.1404 + PluginDestructionGuard guard(this); 1.1405 + 1.1406 + NPError error; 1.1407 + NPBool value = static_cast<NPBool>(enabled); 1.1408 + NS_TRY_SAFE_CALL_RETURN(error, (*pluginFunctions->setvalue)(&mNPP, NPNVprivateModeBool, &value), this, 1.1409 + NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO); 1.1410 + return (error == NPERR_NO_ERROR) ? NS_OK : NS_ERROR_FAILURE; 1.1411 +} 1.1412 + 1.1413 +nsresult 1.1414 +nsNPAPIPluginInstance::IsPrivateBrowsing(bool* aEnabled) 1.1415 +{ 1.1416 + if (!mOwner) 1.1417 + return NS_ERROR_FAILURE; 1.1418 + 1.1419 + nsCOMPtr<nsIDocument> doc; 1.1420 + mOwner->GetDocument(getter_AddRefs(doc)); 1.1421 + NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE); 1.1422 + 1.1423 + nsCOMPtr<nsPIDOMWindow> domwindow = doc->GetWindow(); 1.1424 + NS_ENSURE_TRUE(domwindow, NS_ERROR_FAILURE); 1.1425 + 1.1426 + nsCOMPtr<nsIDocShell> docShell = domwindow->GetDocShell(); 1.1427 + nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(docShell); 1.1428 + *aEnabled = (loadContext && loadContext->UsePrivateBrowsing()); 1.1429 + return NS_OK; 1.1430 +} 1.1431 + 1.1432 +static void 1.1433 +PluginTimerCallback(nsITimer *aTimer, void *aClosure) 1.1434 +{ 1.1435 + nsNPAPITimer* t = (nsNPAPITimer*)aClosure; 1.1436 + NPP npp = t->npp; 1.1437 + uint32_t id = t->id; 1.1438 + 1.1439 + PLUGIN_LOG(PLUGIN_LOG_NOISY, ("nsNPAPIPluginInstance running plugin timer callback this=%p\n", npp->ndata)); 1.1440 + 1.1441 + MAIN_THREAD_JNI_REF_GUARD; 1.1442 + // Some plugins (Flash on Android) calls unscheduletimer 1.1443 + // from this callback. 1.1444 + t->inCallback = true; 1.1445 + (*(t->callback))(npp, id); 1.1446 + t->inCallback = false; 1.1447 + 1.1448 + // Make sure we still have an instance and the timer is still alive 1.1449 + // after the callback. 1.1450 + nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance*)npp->ndata; 1.1451 + if (!inst || !inst->TimerWithID(id, nullptr)) 1.1452 + return; 1.1453 + 1.1454 + // use UnscheduleTimer to clean up if this is a one-shot timer 1.1455 + uint32_t timerType; 1.1456 + t->timer->GetType(&timerType); 1.1457 + if (t->needUnschedule || timerType == nsITimer::TYPE_ONE_SHOT) 1.1458 + inst->UnscheduleTimer(id); 1.1459 +} 1.1460 + 1.1461 +nsNPAPITimer* 1.1462 +nsNPAPIPluginInstance::TimerWithID(uint32_t id, uint32_t* index) 1.1463 +{ 1.1464 + uint32_t len = mTimers.Length(); 1.1465 + for (uint32_t i = 0; i < len; i++) { 1.1466 + if (mTimers[i]->id == id) { 1.1467 + if (index) 1.1468 + *index = i; 1.1469 + return mTimers[i]; 1.1470 + } 1.1471 + } 1.1472 + return nullptr; 1.1473 +} 1.1474 + 1.1475 +uint32_t 1.1476 +nsNPAPIPluginInstance::ScheduleTimer(uint32_t interval, NPBool repeat, void (*timerFunc)(NPP npp, uint32_t timerID)) 1.1477 +{ 1.1478 + if (RUNNING != mRunning) 1.1479 + return 0; 1.1480 + 1.1481 + nsNPAPITimer *newTimer = new nsNPAPITimer(); 1.1482 + 1.1483 + newTimer->inCallback = newTimer->needUnschedule = false; 1.1484 + newTimer->npp = &mNPP; 1.1485 + 1.1486 + // generate ID that is unique to this instance 1.1487 + uint32_t uniqueID = mTimers.Length(); 1.1488 + while ((uniqueID == 0) || TimerWithID(uniqueID, nullptr)) 1.1489 + uniqueID++; 1.1490 + newTimer->id = uniqueID; 1.1491 + 1.1492 + // create new xpcom timer, scheduled correctly 1.1493 + nsresult rv; 1.1494 + nsCOMPtr<nsITimer> xpcomTimer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv); 1.1495 + if (NS_FAILED(rv)) { 1.1496 + delete newTimer; 1.1497 + return 0; 1.1498 + } 1.1499 + const short timerType = (repeat ? (short)nsITimer::TYPE_REPEATING_SLACK : (short)nsITimer::TYPE_ONE_SHOT); 1.1500 + xpcomTimer->InitWithFuncCallback(PluginTimerCallback, newTimer, interval, timerType); 1.1501 + newTimer->timer = xpcomTimer; 1.1502 + 1.1503 + // save callback function 1.1504 + newTimer->callback = timerFunc; 1.1505 + 1.1506 + // add timer to timers array 1.1507 + mTimers.AppendElement(newTimer); 1.1508 + 1.1509 + return newTimer->id; 1.1510 +} 1.1511 + 1.1512 +void 1.1513 +nsNPAPIPluginInstance::UnscheduleTimer(uint32_t timerID) 1.1514 +{ 1.1515 + // find the timer struct by ID 1.1516 + uint32_t index; 1.1517 + nsNPAPITimer* t = TimerWithID(timerID, &index); 1.1518 + if (!t) 1.1519 + return; 1.1520 + 1.1521 + if (t->inCallback) { 1.1522 + t->needUnschedule = true; 1.1523 + return; 1.1524 + } 1.1525 + 1.1526 + // cancel the timer 1.1527 + t->timer->Cancel(); 1.1528 + 1.1529 + // remove timer struct from array 1.1530 + mTimers.RemoveElementAt(index); 1.1531 + 1.1532 + // delete timer 1.1533 + delete t; 1.1534 +} 1.1535 + 1.1536 +// Show the context menu at the location for the current event. 1.1537 +// This can only be called from within an NPP_SendEvent call. 1.1538 +NPError 1.1539 +nsNPAPIPluginInstance::PopUpContextMenu(NPMenu* menu) 1.1540 +{ 1.1541 + if (mOwner && mCurrentPluginEvent) 1.1542 + return mOwner->ShowNativeContextMenu(menu, mCurrentPluginEvent); 1.1543 + 1.1544 + return NPERR_GENERIC_ERROR; 1.1545 +} 1.1546 + 1.1547 +NPBool 1.1548 +nsNPAPIPluginInstance::ConvertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace, 1.1549 + double *destX, double *destY, NPCoordinateSpace destSpace) 1.1550 +{ 1.1551 + if (mOwner) 1.1552 + return mOwner->ConvertPoint(sourceX, sourceY, sourceSpace, destX, destY, destSpace); 1.1553 + 1.1554 + return false; 1.1555 +} 1.1556 + 1.1557 +nsresult 1.1558 +nsNPAPIPluginInstance::GetDOMElement(nsIDOMElement* *result) 1.1559 +{ 1.1560 + if (!mOwner) { 1.1561 + *result = nullptr; 1.1562 + return NS_ERROR_FAILURE; 1.1563 + } 1.1564 + 1.1565 + return mOwner->GetDOMElement(result); 1.1566 +} 1.1567 + 1.1568 +nsresult 1.1569 +nsNPAPIPluginInstance::InvalidateRect(NPRect *invalidRect) 1.1570 +{ 1.1571 + if (RUNNING != mRunning) 1.1572 + return NS_OK; 1.1573 + 1.1574 + if (!mOwner) 1.1575 + return NS_ERROR_FAILURE; 1.1576 + 1.1577 + return mOwner->InvalidateRect(invalidRect); 1.1578 +} 1.1579 + 1.1580 +nsresult 1.1581 +nsNPAPIPluginInstance::InvalidateRegion(NPRegion invalidRegion) 1.1582 +{ 1.1583 + if (RUNNING != mRunning) 1.1584 + return NS_OK; 1.1585 + 1.1586 + if (!mOwner) 1.1587 + return NS_ERROR_FAILURE; 1.1588 + 1.1589 + return mOwner->InvalidateRegion(invalidRegion); 1.1590 +} 1.1591 + 1.1592 +nsresult 1.1593 +nsNPAPIPluginInstance::GetMIMEType(const char* *result) 1.1594 +{ 1.1595 + if (!mMIMEType) 1.1596 + *result = ""; 1.1597 + else 1.1598 + *result = mMIMEType; 1.1599 + 1.1600 + return NS_OK; 1.1601 +} 1.1602 + 1.1603 +nsresult 1.1604 +nsNPAPIPluginInstance::GetJSContext(JSContext* *outContext) 1.1605 +{ 1.1606 + if (!mOwner) 1.1607 + return NS_ERROR_FAILURE; 1.1608 + 1.1609 + nsRefPtr<nsPluginInstanceOwner> deathGrip(mOwner); 1.1610 + 1.1611 + *outContext = nullptr; 1.1612 + nsCOMPtr<nsIDocument> document; 1.1613 + 1.1614 + nsresult rv = mOwner->GetDocument(getter_AddRefs(document)); 1.1615 + 1.1616 + if (NS_SUCCEEDED(rv) && document) { 1.1617 + nsCOMPtr<nsIScriptGlobalObject> global = 1.1618 + do_QueryInterface(document->GetWindow()); 1.1619 + 1.1620 + if (global) { 1.1621 + nsIScriptContext *context = global->GetContext(); 1.1622 + 1.1623 + if (context) { 1.1624 + *outContext = context->GetNativeContext(); 1.1625 + } 1.1626 + } 1.1627 + } 1.1628 + 1.1629 + return rv; 1.1630 +} 1.1631 + 1.1632 +nsPluginInstanceOwner* 1.1633 +nsNPAPIPluginInstance::GetOwner() 1.1634 +{ 1.1635 + return mOwner; 1.1636 +} 1.1637 + 1.1638 +void 1.1639 +nsNPAPIPluginInstance::SetOwner(nsPluginInstanceOwner *aOwner) 1.1640 +{ 1.1641 + mOwner = aOwner; 1.1642 +} 1.1643 + 1.1644 +nsresult 1.1645 +nsNPAPIPluginInstance::ShowStatus(const char* message) 1.1646 +{ 1.1647 + if (mOwner) 1.1648 + return mOwner->ShowStatus(message); 1.1649 + 1.1650 + return NS_ERROR_FAILURE; 1.1651 +} 1.1652 + 1.1653 +nsresult 1.1654 +nsNPAPIPluginInstance::AsyncSetWindow(NPWindow& window) 1.1655 +{ 1.1656 + return NS_ERROR_NOT_IMPLEMENTED; 1.1657 +} 1.1658 + 1.1659 +void 1.1660 +nsNPAPIPluginInstance::URLRedirectResponse(void* notifyData, NPBool allow) 1.1661 +{ 1.1662 + if (!notifyData) { 1.1663 + return; 1.1664 + } 1.1665 + 1.1666 + uint32_t listenerCount = mStreamListeners.Length(); 1.1667 + for (uint32_t i = 0; i < listenerCount; i++) { 1.1668 + nsNPAPIPluginStreamListener* currentListener = mStreamListeners[i]; 1.1669 + if (currentListener->GetNotifyData() == notifyData) { 1.1670 + currentListener->URLRedirectResponse(allow); 1.1671 + } 1.1672 + } 1.1673 +} 1.1674 + 1.1675 +NPError 1.1676 +nsNPAPIPluginInstance::InitAsyncSurface(NPSize *size, NPImageFormat format, 1.1677 + void *initData, NPAsyncSurface *surface) 1.1678 +{ 1.1679 + if (mOwner) 1.1680 + return mOwner->InitAsyncSurface(size, format, initData, surface); 1.1681 + 1.1682 + return NPERR_GENERIC_ERROR; 1.1683 +} 1.1684 + 1.1685 +NPError 1.1686 +nsNPAPIPluginInstance::FinalizeAsyncSurface(NPAsyncSurface *surface) 1.1687 +{ 1.1688 + if (mOwner) 1.1689 + return mOwner->FinalizeAsyncSurface(surface); 1.1690 + 1.1691 + return NPERR_GENERIC_ERROR; 1.1692 +} 1.1693 + 1.1694 +void 1.1695 +nsNPAPIPluginInstance::SetCurrentAsyncSurface(NPAsyncSurface *surface, NPRect *changed) 1.1696 +{ 1.1697 + if (mOwner) 1.1698 + mOwner->SetCurrentAsyncSurface(surface, changed); 1.1699 +} 1.1700 + 1.1701 +class CarbonEventModelFailureEvent : public nsRunnable { 1.1702 +public: 1.1703 + nsCOMPtr<nsIContent> mContent; 1.1704 + 1.1705 + CarbonEventModelFailureEvent(nsIContent* aContent) 1.1706 + : mContent(aContent) 1.1707 + {} 1.1708 + 1.1709 + ~CarbonEventModelFailureEvent() {} 1.1710 + 1.1711 + NS_IMETHOD Run(); 1.1712 +}; 1.1713 + 1.1714 +NS_IMETHODIMP 1.1715 +CarbonEventModelFailureEvent::Run() 1.1716 +{ 1.1717 + nsString type = NS_LITERAL_STRING("npapi-carbon-event-model-failure"); 1.1718 + nsContentUtils::DispatchTrustedEvent(mContent->GetDocument(), mContent, 1.1719 + type, true, true); 1.1720 + return NS_OK; 1.1721 +} 1.1722 + 1.1723 +void 1.1724 +nsNPAPIPluginInstance::CarbonNPAPIFailure() 1.1725 +{ 1.1726 + nsCOMPtr<nsIDOMElement> element; 1.1727 + GetDOMElement(getter_AddRefs(element)); 1.1728 + if (!element) { 1.1729 + return; 1.1730 + } 1.1731 + 1.1732 + nsCOMPtr<nsIContent> content(do_QueryInterface(element)); 1.1733 + if (!content) { 1.1734 + return; 1.1735 + } 1.1736 + 1.1737 + nsCOMPtr<nsIRunnable> e = new CarbonEventModelFailureEvent(content); 1.1738 + nsresult rv = NS_DispatchToCurrentThread(e); 1.1739 + if (NS_FAILED(rv)) { 1.1740 + NS_WARNING("Failed to dispatch CarbonEventModelFailureEvent."); 1.1741 + } 1.1742 +} 1.1743 + 1.1744 +static bool 1.1745 +GetJavaVersionFromMimetype(nsPluginTag* pluginTag, nsCString& version) 1.1746 +{ 1.1747 + for (uint32_t i = 0; i < pluginTag->mMimeTypes.Length(); ++i) { 1.1748 + nsCString type = pluginTag->mMimeTypes[i]; 1.1749 + nsAutoCString jpi("application/x-java-applet;jpi-version="); 1.1750 + 1.1751 + int32_t idx = type.Find(jpi, false, 0, -1); 1.1752 + if (idx != 0) { 1.1753 + continue; 1.1754 + } 1.1755 + 1.1756 + type.Cut(0, jpi.Length()); 1.1757 + if (type.IsEmpty()) { 1.1758 + continue; 1.1759 + } 1.1760 + 1.1761 + type.ReplaceChar('_', '.'); 1.1762 + version = type; 1.1763 + return true; 1.1764 + } 1.1765 + 1.1766 + return false; 1.1767 +} 1.1768 + 1.1769 +void 1.1770 +nsNPAPIPluginInstance::CheckJavaC2PJSObjectQuirk(uint16_t paramCount, 1.1771 + const char* const* paramNames, 1.1772 + const char* const* paramValues) 1.1773 +{ 1.1774 + if (!mMIMEType || !mPlugin) { 1.1775 + return; 1.1776 + } 1.1777 + 1.1778 + nsPluginTagType tagtype; 1.1779 + nsresult rv = GetTagType(&tagtype); 1.1780 + if (NS_FAILED(rv) || 1.1781 + (tagtype != nsPluginTagType_Applet)) { 1.1782 + return; 1.1783 + } 1.1784 + 1.1785 + nsRefPtr<nsPluginHost> pluginHost = nsPluginHost::GetInst(); 1.1786 + if (!pluginHost) { 1.1787 + return; 1.1788 + } 1.1789 + 1.1790 + nsPluginTag* pluginTag = pluginHost->TagForPlugin(mPlugin); 1.1791 + if (!pluginTag || 1.1792 + !pluginTag->mIsJavaPlugin) { 1.1793 + return; 1.1794 + } 1.1795 + 1.1796 + // check the params for "code" being present and non-empty 1.1797 + bool haveCodeParam = false; 1.1798 + bool isCodeParamEmpty = true; 1.1799 + 1.1800 + for (uint16_t i = paramCount; i > 0; --i) { 1.1801 + if (PL_strcasecmp(paramNames[i - 1], "code") == 0) { 1.1802 + haveCodeParam = true; 1.1803 + if (strlen(paramValues[i - 1]) > 0) { 1.1804 + isCodeParamEmpty = false; 1.1805 + } 1.1806 + break; 1.1807 + } 1.1808 + } 1.1809 + 1.1810 + // Due to the Java version being specified inconsistently across platforms 1.1811 + // check the version via the mimetype for choosing specific Java versions 1.1812 + nsCString javaVersion; 1.1813 + if (!GetJavaVersionFromMimetype(pluginTag, javaVersion)) { 1.1814 + return; 1.1815 + } 1.1816 + 1.1817 + mozilla::Version version = javaVersion.get(); 1.1818 + 1.1819 + if (version >= "1.7.0.4") { 1.1820 + return; 1.1821 + } 1.1822 + 1.1823 + if (!haveCodeParam && version >= "1.6.0.34" && version < "1.7") { 1.1824 + return; 1.1825 + } 1.1826 + 1.1827 + if (haveCodeParam && !isCodeParamEmpty) { 1.1828 + return; 1.1829 + } 1.1830 + 1.1831 + mHaveJavaC2PJSObjectQuirk = true; 1.1832 +} 1.1833 + 1.1834 +double 1.1835 +nsNPAPIPluginInstance::GetContentsScaleFactor() 1.1836 +{ 1.1837 + double scaleFactor = 1.0; 1.1838 + if (mOwner) { 1.1839 + mOwner->GetContentsScaleFactor(&scaleFactor); 1.1840 + } 1.1841 + return scaleFactor; 1.1842 +}