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