dom/plugins/base/nsNPAPIPluginInstance.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial